Commit 4f568633 authored by Alexandre Julliard's avatar Alexandre Julliard

Authors: Jason Edmeades <us@the-edmeades.demon.co.uk>, Christian Costa <titan.costa@wanadoo.fr>

Added support for vertex shader (using ARB_vertex_program extension).
parent a45931c6
......@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = d3d8.dll
IMPORTS = user32 gdi32 kernel32
IMPORTS = user32 gdi32 kernel32 advapi32
EXTRAINCL = @X_CFLAGS@
EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
......
......@@ -22,6 +22,7 @@
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
......@@ -34,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
int num_lock = 0;
void (*wine_tsx11_lock_ptr)(void) = NULL;
void (*wine_tsx11_unlock_ptr)(void) = NULL;
int vs_mode;
HRESULT WINAPI D3D8GetSWInfo(void)
{
......@@ -64,18 +66,39 @@ IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion)
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
TRACE("D3D8 DLLMain Reason=%ld\n", fdwReason);
if (fdwReason == DLL_PROCESS_ATTACH)
{
HMODULE mod;
if (fdwReason == DLL_PROCESS_ATTACH)
{
HMODULE mod;
char buffer[32];
DWORD size = sizeof(buffer);
HKEY hkey = 0;
DisableThreadLibraryCalls(hInstDLL);
DisableThreadLibraryCalls(hInstDLL);
mod = GetModuleHandleA( "x11drv.dll" );
if (mod)
mod = GetModuleHandleA( "x11drv.dll" );
if (mod)
{
wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
}
if ( !RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\d3d", &hkey) &&
!RegQueryValueExA( hkey, "vs_mode", 0, NULL, buffer, &size) )
{
if (!strcmp(buffer,"none"))
{
TRACE("Disable vertex shader\n");
vs_mode = VS_NONE;
}
else if (!strcmp(buffer,"emulation"))
{
wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
TRACE("Force SW vertex shader\n");
vs_mode = VS_SW;
}
else {
TRACE("Allow HW vertex shader\n");
vs_mode = VS_HW;
}
}
}
return TRUE;
}
/*
* Direct3D 8 private include file
*
* Copyright 2002 Jason Edmeades
* Copyright 2002-2004 Jason Edmeades
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -28,6 +29,7 @@
/* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES */
#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */
#include <GL/gl.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#ifdef HAVE_GL_GLEXT_H
# include <GL/glext.h>
......@@ -64,6 +66,11 @@ extern int num_lock;
#include "winbase.h"
#include "d3d8.h"
extern int vs_mode;
#define VS_NONE 0
#define VS_HW 1
#define VS_SW 2
/* Device caps */
#define MAX_PALETTES 256
#define MAX_STREAMS 16
......@@ -1198,6 +1205,10 @@ struct IDirect3DVertexShaderImpl {
UINT functionLength;
DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */
DWORD version;
/** fields for hw vertex shader use */
GLuint prgId;
/* run time datas */
VSHADERDATA8* data;
VSHADERINPUTDATA8 input;
......@@ -1217,7 +1228,8 @@ extern DWORD WINAPI IDirect3DVertexShaderImpl_GetVersion(IDirect3DVertexShaderIm
extern HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* This, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output);
/* temporary internal Interfaces */
extern HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, DWORD Usage, IDirect3DVertexShaderImpl** ppVertexShader);
extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides);
extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputSW(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides);
extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputArbHW(IDirect3DDevice8Impl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides);
/* ------------------------ */
/* IDirect3DPixelShaderImpl */
......
......@@ -1248,7 +1248,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, I
return D3D_OK;
}
TRACE("(%p) : expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
FIXME("(%p) : expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
hr = IDirect3DDevice8Impl_ActiveRender(iface, pRenderTarget, pNewZStencil);
......@@ -3920,6 +3920,9 @@ HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface
TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object);
/* TODO: check validity of object */
if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
if (object->prgId != 0) {
GL_EXTCALL(glDeleteProgramsARB( 1, &object->prgId ));
}
HeapFree(GetProcessHeap(), 0, (void *)object->data);
HeapFree(GetProcessHeap(), 0, (void *)object);
VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
......
/*
* IDirect3D8 implementation
*
* Copyright 2002 Jason Edmeades
* Copyright 2002-2004 Jason Edmeades
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -313,6 +314,7 @@ HRESULT WINAPI IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 iface,
case D3DFMT_X8L8V8U8:
case D3DFMT_L6V5U5:
case D3DFMT_V8U8:
case D3DFMT_L8:
/* Since we do not support these formats right now, don't pretend to. */
return D3DERR_NOTAVAILABLE;
default:
......@@ -646,6 +648,7 @@ HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D
#if defined(GL_EXT_texture_filter_anisotropic)
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
checkGLcall("glGetInterv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)");
pCaps->MaxAnisotropy = gl_max;
#else
pCaps->MaxAnisotropy = 0;
......@@ -668,13 +671,11 @@ HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D
pCaps->MaxStreams = MAX_STREAMS;
pCaps->MaxStreamStride = 1024;
#if 1
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
pCaps->MaxVertexShaderConst = D3D8_VSHADER_MAX_CONSTANTS;
#else
pCaps->VertexShaderVersion = 0;
if (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) || (vs_mode == VS_SW) || (DeviceType == D3DDEVTYPE_REF))
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
else
pCaps->VertexShaderVersion = 0;
pCaps->MaxVertexShaderConst = D3D8_VSHADER_MAX_CONSTANTS;
#endif
#if 0
pCaps->PixelShaderVersion = D3DPS_VERSION(1,1);
......
......@@ -2,6 +2,8 @@
* vertex shaders declaration implementation
*
* Copyright 2002 Raphael Junqueira
* Copyright 2004 Jason Edmeades
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -201,6 +203,7 @@ HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDevic
TRACE("(%p) : pDeclaration8(%p)\n", This, pDeclaration8);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexShaderDeclarationImpl));
/*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/
object->device = This; /* FIXME: AddRef(This) */
object->ref = 1;
......@@ -376,10 +379,9 @@ HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDevic
return D3D_OK;
}
HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This,
IDirect3DVertexShaderImpl* vshader,
DWORD SkipnStrides) {
HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputSW(IDirect3DDevice8Impl* This,
IDirect3DVertexShaderImpl* vshader,
DWORD SkipnStrides) {
/** parser data */
const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8;
DWORD stream = 0;
......@@ -564,6 +566,149 @@ HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* T
return D3D_OK;
}
HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInputArbHW(IDirect3DDevice8Impl* This,
IDirect3DVertexShaderImpl* vshader,
DWORD SkipnStrides) {
/** parser data */
const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8;
DWORD stream = 0;
DWORD token;
/*DWORD tokenlen;*/
DWORD tokentype;
/** for input readers */
const char* curPos = NULL;
int skip = 0;
TRACE("(%p) - This:%p, skipstrides=%lu\n", vshader, This, SkipnStrides);
while (D3DVSD_END() != *pToken) {
token = *pToken;
tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
/** FVF generation block */
if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
IDirect3DVertexBuffer8* pVB;
++pToken;
/**
* how really works streams,
* in DolphinVS dx8 dsk sample use it !!!
*/
stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
skip = This->StateBlock->stream_stride[stream];
pVB = This->StateBlock->stream_source[stream];
if (NULL == pVB) {
ERR("using unitialised stream[%lu]\n", stream);
return D3DERR_INVALIDCALL;
} else {
if (This->StateBlock->streamIsUP == TRUE) {
curPos = ((char *) pVB) + (SkipnStrides * skip); /* Not really a VB */
} else {
curPos = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (SkipnStrides * skip);
}
TRACE(" using stream[%lu] with %p (%p + (Stride %d * skip %ld))\n", stream, curPos,
((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory, skip, SkipnStrides);
}
} else if (D3DVSD_TOKEN_CONSTMEM == tokentype) {
/** Const decl */
DWORD i;
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
++pToken;
for (i = 0; i < count; ++i) {
FIXME("Confirm this is correct handling of consts inside the hw vertex shader\n");
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, constaddress+i, (GLfloat *)pToken));
vshader->data->C[constaddress + i].x = *(float*)pToken;
vshader->data->C[constaddress + i].y = *(float*)(pToken + 1);
vshader->data->C[constaddress + i].z = *(float*)(pToken + 2);
vshader->data->C[constaddress + i].w = *(float*)(pToken + 3);
pToken += 4;
}
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) {
/** skip datas */
DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
TRACE(" skipping %ld dwords\n", skipCount);
curPos = curPos + skipCount * sizeof(DWORD);
++pToken;
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
++pToken;
TRACE(" type : %ld, reg = %ld\n", type, reg);
switch (type) {
case D3DVSDT_FLOAT1:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 1, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 1, GL_FLOAT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + sizeof(float);
break;
case D3DVSDT_FLOAT2:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 2, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 2, GL_FLOAT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 2*sizeof(float);
break;
case D3DVSDT_FLOAT3:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 3, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 3, GL_FLOAT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 3*sizeof(float);
break;
case D3DVSDT_FLOAT4:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 4, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_FLOAT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 4*sizeof(float);
break;
case D3DVSDT_D3DCOLOR:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 4, skip, curPos);
FIXME("D3DVSDT_D3DCOLOR in hw shader - To confirm\n");
GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_BYTE, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 4*sizeof(BYTE);
break;
case D3DVSDT_SHORT2:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 2, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 2, GL_UNSIGNED_SHORT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 2*sizeof(short int);
break;
case D3DVSDT_SHORT4:
TRACE("HW VS glVertexAttribPointerARB(reg=%ld,num=%d,skip=%d,ptr=%p)\n", reg, 1, skip, curPos);
GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_SHORT, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 4*sizeof(short int);
break;
case D3DVSDT_UBYTE4:
FIXME("D3DVSDT_UBYTE4 in hw shader - To confirm\n");
GL_EXTCALL(glVertexAttribPointerARB(reg, 4, GL_UNSIGNED_BYTE, GL_FALSE, skip, curPos));
GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
curPos = curPos + 4*sizeof(BYTE);
break;
default: /** errooooorr what to do ? */
ERR("Error in VertexShader declaration of %s register: unsupported type %s\n", VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
}
}
}
/* here D3DVSD_END() */
return D3D_OK;
}
HRESULT WINAPI IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(IDirect3DVertexShaderDeclarationImpl* This, DWORD* pData, UINT* pSizeOfData) {
if (NULL == pData) {
*pSizeOfData = This->declaration8Length;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment