From b050a3dbf16e75cf1900a093291864c0a69df606 Mon Sep 17 00:00:00 2001 From: Raphael Junqueira Date: Wed, 4 Jun 2003 22:45:57 +0000 Subject: [PATCH] - pixel shader program dump code - pixel shader code split into a new "COM object" (as done before for vertex shader) - some fixes on Validate* functions call types - add pixel shader (ie fragment_program) detection on caps code --- dlls/d3d8/d3d8.spec | 2 +- dlls/d3d8/d3d8_main.c | 5 +- dlls/d3d8/d3d8_private.h | 71 +++++- dlls/d3d8/device.c | 131 ++++++---- dlls/d3d8/directx.c | 18 +- dlls/d3d8/shader.c | 518 ++++++++++++++++++++++++++++++++++++--- 6 files changed, 640 insertions(+), 105 deletions(-) diff --git a/dlls/d3d8/d3d8.spec b/dlls/d3d8/d3d8.spec index 12c4c395136..6c9d43d73cf 100644 --- a/dlls/d3d8/d3d8.spec +++ b/dlls/d3d8/d3d8.spec @@ -1,5 +1,5 @@ @ stdcall D3D8GetSWInfo() -@ stdcall DebugSetMute(long) +@ stdcall DebugSetMute() @ stdcall Direct3DCreate8(long) @ stdcall ValidatePixelShader(ptr ptr) @ stdcall ValidateVertexShader(ptr ptr) diff --git a/dlls/d3d8/d3d8_main.c b/dlls/d3d8/d3d8_main.c index fe188c16455..6803c07020b 100644 --- a/dlls/d3d8/d3d8_main.c +++ b/dlls/d3d8/d3d8_main.c @@ -38,10 +38,9 @@ HRESULT WINAPI D3D8GetSWInfo(void) return 0; } -HRESULT WINAPI DebugSetMute(void) +void DebugSetMute(void) { - FIXME("(void): stub\n"); - return 0; + /* nothing to do */ } IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index a2d4a50979c..6a9f1392c37 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -99,17 +99,16 @@ typedef struct D3DSHADERSCALAR { } D3DSHADERSCALAR; #define D3D8_VSHADER_MAX_CONSTANTS 96 -#define D3D8_PSHADER_MAX_CONSTANTS 96 typedef D3DSHADERVECTOR VSHADERCONSTANTS8[D3D8_VSHADER_MAX_CONSTANTS]; -typedef struct SHADERDATA8 { +typedef struct VSHADERDATA8 { /** Run Time Shader Function Constants */ /*D3DXBUFFER* constants;*/ VSHADERCONSTANTS8 C; /** Shader Code as char ... */ CONST DWORD* code; UINT codeLength; -} SHADERDATA8; +} VSHADERDATA8; /** temporary here waiting for buffer code */ typedef struct VSHADERINPUTDATA8 { @@ -125,6 +124,34 @@ typedef struct VSHADEROUTPUTDATA8 { D3DSHADERVECTOR oPts; } VSHADEROUTPUTDATA8; + +#define D3D8_PSHADER_MAX_CONSTANTS 32 +typedef D3DSHADERVECTOR PSHADERCONSTANTS8[D3D8_PSHADER_MAX_CONSTANTS]; + +typedef struct PSHADERDATA8 { + /** Run Time Shader Function Constants */ + /*D3DXBUFFER* constants;*/ + PSHADERCONSTANTS8 C; + /** Shader Code as char ... */ + CONST DWORD* code; + UINT codeLength; +} PSHADERDATA8; + +/** temporary here waiting for buffer code */ +typedef struct PSHADERINPUTDATA8 { + D3DSHADERVECTOR V[2]; + D3DSHADERVECTOR T[8]; + D3DSHADERVECTOR S[16]; + /*D3DSHADERVECTOR R[12];*/ +} PSHADERINPUTDATA8; + +/** temporary here waiting for buffer code */ +typedef struct PSHADEROUTPUTDATA8 { + D3DSHADERVECTOR oC[4]; + D3DSHADERVECTOR oDepth; +} PSHADEROUTPUTDATA8; + + /* * External prototypes */ @@ -155,6 +182,7 @@ void CreateStateBlock(LPDIRECT3DDEVICE8 iface); typedef enum _GL_SupportedExt { /* ARB */ + ARB_FRAGMENT_PROGRAM, ARB_MULTISAMPLE, ARB_MULTITEXTURE, ARB_POINT_PARAMETERS, @@ -173,6 +201,7 @@ typedef enum _GL_SupportedExt { EXT_TEXTURE_LOD_BIAS, EXT_VERTEX_WEIGHTING, /* NVIDIA */ + NV_FRAGMENT_PROGRAM, NV_VERTEX_PROGRAM, /* ATI */ EXT_VERTEX_SHADER, @@ -190,6 +219,19 @@ typedef enum _GL_VSVersion { VS_VERSION_FORCE_DWORD = 0x7FFFFFFF } GL_VSVersion; +typedef enum _GL_PSVersion { + PS_VERSION_NOT_SUPPORTED = 0x0, + PS_VERSION_10 = 0x10, + PS_VERSION_11 = 0x11, + PS_VERSION_12 = 0x12, + PS_VERSION_13 = 0x13, + PS_VERSION_14 = 0x14, + PS_VERSION_20 = 0x20, + PS_VERSION_30 = 0x30, + /*Force 32-bits*/ + PS_VERSION_FORCE_DWORD = 0x7FFFFFFF +} GL_PSVersion; + typedef struct _GL_Info { /** * CAPS Constants @@ -198,11 +240,14 @@ typedef struct _GL_Info { UINT max_textures; UINT max_clipplanes; + GL_PSVersion ps_arb_version; + GL_PSVersion ps_nv_version; + GL_VSVersion vs_arb_version; GL_VSVersion vs_nv_version; GL_VSVersion vs_ati_version; - BOOL supported[25]; + BOOL supported[30]; } GL_Info; #define GL_LIMITS(ExtName) (This->direct3d8->gl_info.max_##ExtName) @@ -1017,6 +1062,7 @@ typedef struct SAVEDSTATES { BOOL vertexShaderConstant; BOOL vertexShaderDecl; BOOL pixelShader; + BOOL pixelShaderConstant; BOOL renderstate[HIGHEST_RENDER_STATE]; BOOL texture_state[8][HIGHEST_TEXTURE_STATE]; BOOL clipplane[MAX_CLIPPLANES]; @@ -1091,7 +1137,6 @@ struct IDirect3DStateBlockImpl { /* Pixel Shader */ DWORD PixelShader; - /* TODO: Pixel Shader Constant */ /* Indexed Vertex Blending */ D3DVERTEXBLENDFLAGS vertex_blend; @@ -1099,6 +1144,8 @@ struct IDirect3DStateBlockImpl { /* Vertex Shader Constant */ D3DSHADERVECTOR vertexShaderConstant[D3D8_VSHADER_MAX_CONSTANTS]; + /* Pixel Shader Constant */ + D3DSHADERVECTOR pixelShaderConstant[D3D8_PSHADER_MAX_CONSTANTS]; }; /* exported Interfaces */ @@ -1171,7 +1218,7 @@ struct IDirect3DVertexShaderImpl { DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */ DWORD version; /* run time datas */ - SHADERDATA8* data; + VSHADERDATA8* data; VSHADERINPUTDATA8 input; VSHADEROUTPUTDATA8 output; }; @@ -1210,18 +1257,21 @@ struct IDirect3DPixelShaderImpl { /* The device, to be replaced by a IDirect3DDeviceImpl */ IDirect3DDevice8Impl* device; - /* TODO: Pixel Shader */ - CONST DWORD* function; + DWORD* function; UINT functionLength; DWORD version; /* run time datas */ - SHADERDATA8* data; + PSHADERDATA8* data; + PSHADERINPUTDATA8 input; + PSHADEROUTPUTDATA8 output; }; /* exported Interfaces */ extern HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData); /* internal Interfaces */ extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl* This); +/* temporary internal Interfaces */ +extern HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader); /** @@ -1229,7 +1279,10 @@ extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl * * to see how not defined it here */ +void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand); void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage); +void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); + SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt); GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt); diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index b18b584bbe8..032d420a4f5 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -3570,7 +3570,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD IDirect3DBaseTexture8Impl_AddRef(*ppTexture); return D3D_OK; } -HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) { +HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) { IDirect3DBaseTexture8 *oldTxt; BOOL reapplyStates = TRUE; @@ -3610,22 +3610,20 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD } /* Decrement the count of the previous texture */ - if (oldTxt != NULL) { + if (NULL != oldTxt) { IDirect3DBaseTexture8Impl_Release(oldTxt); } - if (pTexture) { - IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]); + if (NULL != pTexture) { + IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]); /* Now setup the texture appropraitly */ textureType = IDirect3DBaseTexture8Impl_GetType(pTexture); if (textureType == D3DRTYPE_TEXTURE) { - IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl*) pTexture; - - if ((void*) oldTxt == (void*) pTexture2 && pTexture2->Dirty == FALSE) { - TRACE("Skipping setting texture as old == new\n"); - reapplyStates = FALSE; + if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { + TRACE("Skipping setting texture as old == new\n"); + reapplyStates = FALSE; } else { /* Standard 2D texture */ TRACE("Standard 2d texture\n"); @@ -3635,19 +3633,29 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture); } } else if (textureType == D3DRTYPE_VOLUMETEXTURE) { - /* Standard 3D (volume) texture */ + if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { + TRACE("Skipping setting texture as old == new\n"); + reapplyStates = FALSE; + } else { + /* Standard 3D (volume) texture */ TRACE("Standard 3d texture\n"); This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D; /* Load up the texture now */ IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture); + } } else if (textureType == D3DRTYPE_CUBETEXTURE) { + if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) { + TRACE("Skipping setting texture as old == new\n"); + reapplyStates = FALSE; + } else { /* Standard Cube texture */ TRACE("Standard Cube texture\n"); This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB; /* Load up the texture now */ IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture); + } } else { FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType)); } @@ -3662,7 +3670,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */ if (reapplyStates) { - setupTextureStates (iface, Stage); + setupTextureStates(iface, Stage); } return D3D_OK; @@ -4439,9 +4447,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirec HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) { ICOM_THIS(IDirect3DDevice8Impl,iface); IDirect3DPixelShaderImpl* object; + HRESULT res; UINT i; - FIXME("(%p) : PixelShader not fully supported yet\n", This); + TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction); if (NULL == pFunction || NULL == pHandle) { return D3DERR_INVALIDCALL; } @@ -4449,21 +4458,16 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) { return D3DERR_OUTOFVIDEOMEMORY; } - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl)); - if (NULL == object) { - return D3DERR_OUTOFVIDEOMEMORY; - } - - object->data = NULL; /* TODO */ - PixelShaders[i] = object; - *pHandle = VS_HIGHESTFIXEDFXF + i; - - object->function = pFunction; - for (i = 0; D3DPS_END() != pFunction[i]; ++i) ; - object->functionLength = i + 1; - - return D3D_OK; + /** Create the Pixel Shader */ + res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object); + if (SUCCEEDED(res)) { + PixelShaders[i] = object; + *pHandle = VS_HIGHESTFIXEDFXF + i; + return D3D_OK; + } + *pHandle = 0xFFFFFFFF; + return res; } HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { ICOM_THIS(IDirect3DDevice8Impl,iface); @@ -4474,22 +4478,22 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DW /* Handle recording of state blocks */ if (This->isRecordingState) { - TRACE("Recording... not performing anything\n"); + TRACE_(d3d_shader)("Recording... not performing anything\n"); return D3D_OK; } /* FIXME: Quieten when not being used */ if (Handle != 0) { - FIXME("(%p) : stub %ld\n", This, Handle); + FIXME_(d3d_shader)("(%p) : stub %ld\n", This, Handle); } else { - TRACE("(%p) : stub %ld\n", This, Handle); + TRACE_(d3d_shader)("(%p) : stub %ld\n", This, Handle); } return D3D_OK; } HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) { ICOM_THIS(IDirect3DDevice8Impl,iface); - TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader); + TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader); *pHandle = This->StateBlock->PixelShader; return D3D_OK; } @@ -4502,42 +4506,63 @@ HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, return D3DERR_INVALIDCALL; } object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF]; - TRACE("(%p) : freeing PixelShader %p\n", This, object); + TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object); /* TODO: check validity of object before free */ + if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function); + HeapFree(GetProcessHeap(), 0, (void *)object->data); HeapFree(GetProcessHeap(), 0, (void *)object); - PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0; + PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL; + return D3D_OK; } -HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) { - ICOM_THIS(IDirect3DDevice8Impl,iface); - FIXME("(%p) : stub\n", This); - return D3D_OK; +HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) { + ICOM_THIS(IDirect3DDevice8Impl,iface); + + if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) { + ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register); + return D3DERR_INVALIDCALL; + } + if (NULL == pConstantData) { + return D3DERR_INVALIDCALL; + } + if (ConstantCount > 1) { + FLOAT* f = (FLOAT*)pConstantData; + UINT i; + TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1); + for (i = 0; i < ConstantCount; ++i) { + TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]); + f += 4; + } + } else { + FLOAT* f = (FLOAT*) pConstantData; + TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]); + } + This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE; + memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT)); + return D3D_OK; } -HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) { - ICOM_THIS(IDirect3DDevice8Impl,iface); - FIXME("(%p) : stub\n", This); - return D3D_OK; +HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) { + ICOM_THIS(IDirect3DDevice8Impl,iface); + + TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount); + if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) { + return D3DERR_INVALIDCALL; + } + if (NULL == pConstantData) { + return D3DERR_INVALIDCALL; + } + memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT)); + return D3D_OK; } HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) { - ICOM_THIS(IDirect3DDevice8Impl,iface); IDirect3DPixelShaderImpl* object; object = PIXEL_SHADER(Handle); if (NULL == object) { return D3DERR_INVALIDCALL; - } - if (NULL == pData) { - *pSizeOfData = object->functionLength; - return D3D_OK; - } - if (*pSizeOfData < object->functionLength) { - *pSizeOfData = object->functionLength; - return D3DERR_MOREDATA; - } - TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData); - memcpy(pData, object->function, object->functionLength); - return D3D_OK; + } + return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData); } HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) { ICOM_THIS(IDirect3DDevice8Impl,iface); diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index cac08332741..479783e3e3d 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -681,12 +681,6 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, int dblBuf[] = {GLX_RGBA, GLX_STENCIL_SIZE, 8, /* 2 */ GLX_DEPTH_SIZE, 16, /* 4 */ -#if 0 - GLX_RED_SIZE, 8, /* 6 */ - GLX_GREEN_SIZE, 8, /* 8 */ - GLX_BLUE_SIZE, 8, /* 10 */ - GLX_ALPHA_SIZE, 8, /* 12 */ -#endif GLX_DOUBLEBUFFER, None}; /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */ @@ -889,8 +883,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, */ memset(&This->gl_info.supported, 0, sizeof(This->gl_info.supported)); This->gl_info.max_textures = 1; + This->gl_info.ps_arb_version = PS_VERSION_NOT_SUPPORTED; This->gl_info.vs_arb_version = VS_VERSION_NOT_SUPPORTED; This->gl_info.vs_nv_version = VS_VERSION_NOT_SUPPORTED; + This->gl_info.vs_ati_version = VS_VERSION_NOT_SUPPORTED; /* Retrieve opengl defaults */ glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max); @@ -922,7 +918,11 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, /** * ARB */ - if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) { + if (strcmp(ThisExtn, "GL_ARB_fragment_program") == 0) { + This->gl_info.ps_arb_version = PS_VERSION_11; + FIXME(" FOUND: ARB Pixel Shader support - version=%02x\n", This->gl_info.ps_arb_version); + This->gl_info.supported[ARB_FRAGMENT_PROGRAM] = TRUE; + } else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) { FIXME(" FOUND: ARB Multisample support\n"); This->gl_info.supported[ARB_MULTISAMPLE] = TRUE; } else if (strcmp(ThisExtn, "GL_ARB_multitexture") == 0) { @@ -976,6 +976,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, /** * NVIDIA */ + } else if (strstr(ThisExtn, "GL_NV_fragment_program")) { + This->gl_info.ps_nv_version = PS_VERSION_11; + FIXME(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This->gl_info.ps_nv_version); + This->gl_info.supported[NV_FRAGMENT_PROGRAM] = TRUE; } else if (strstr(ThisExtn, "GL_NV_vertex_program")) { This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10); This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2")) ? VS_VERSION_20 : VS_VERSION_10); diff --git a/dlls/d3d8/shader.c b/dlls/d3d8/shader.c index 84cb55ecfd5..22da6f0c76f 100644 --- a/dlls/d3d8/shader.c +++ b/dlls/d3d8/shader.c @@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); /* Shader debugging - Change the following line to enable debugging of software vertex shaders */ -#if 1 +#if 0 # define VSTRACE(A) TRACE A # define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w) #else @@ -82,6 +82,8 @@ typedef struct SHADER_OPCODE { const char* name; CONST UINT num_params; shader_fct_t soft_fct; + DWORD min_version; + DWORD max_version; } SHADER_OPCODE; /******************************* @@ -345,36 +347,36 @@ void vshader_lrp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D * log, exp, frc, m*x* seems to be macros ins ... to see */ static CONST SHADER_OPCODE vshader_ins [] = { - {D3DSIO_NOP, "nop", 0, vshader_nop}, - {D3DSIO_MOV, "mov", 2, vshader_mov}, - {D3DSIO_ADD, "add", 3, vshader_add}, - {D3DSIO_SUB, "sub", 3, vshader_sub}, - {D3DSIO_MAD, "mad", 4, vshader_mad}, - {D3DSIO_MUL, "mul", 3, vshader_mul}, - {D3DSIO_RCP, "rcp", 2, vshader_rcp}, - {D3DSIO_RSQ, "rsq", 2, vshader_rsq}, - {D3DSIO_DP3, "dp3", 3, vshader_dp3}, - {D3DSIO_DP4, "dp4", 3, vshader_dp4}, - {D3DSIO_MIN, "min", 3, vshader_min}, - {D3DSIO_MAX, "max", 3, vshader_max}, - {D3DSIO_SLT, "slt", 3, vshader_slt}, - {D3DSIO_SGE, "sge", 3, vshader_sge}, - {D3DSIO_EXP, "exp", 2, vshader_exp}, - {D3DSIO_LOG, "log", 2, vshader_log}, - {D3DSIO_LIT, "lit", 2, vshader_lit}, - {D3DSIO_DST, "dst", 3, vshader_dst}, - {D3DSIO_LRP, "lrp", 5, vshader_lrp}, - {D3DSIO_FRC, "frc", 2, vshader_frc}, - {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4}, - {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3}, - {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4}, - {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3}, - {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2}, + {D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0}, + {D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0}, + {D3DSIO_ADD, "add", 3, vshader_add, 0, 0}, + {D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0}, + {D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0}, + {D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0}, + {D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0}, + {D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0}, + {D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0}, + {D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0}, + {D3DSIO_MIN, "min", 3, vshader_min, 0, 0}, + {D3DSIO_MAX, "max", 3, vshader_max, 0, 0}, + {D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0}, + {D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0}, + {D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0}, + {D3DSIO_LOG, "log", 2, vshader_log, 0, 0}, + {D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0}, + {D3DSIO_DST, "dst", 3, vshader_dst, 0, 0}, + {D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0}, + {D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0}, + {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0}, + {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0}, + {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0}, + {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0}, + {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0}, /** FIXME: use direct access so add the others opcodes as stubs */ - {D3DSIO_EXPP, "expp", 2, vshader_expp}, - {D3DSIO_LOGP, "logp", 2, vshader_logp}, + {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0}, + {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0}, - {0, NULL, 0, NULL} + {0, NULL, 0, NULL, 0, 0} }; @@ -546,7 +548,7 @@ HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This object->ref = 1; object->usage = Usage; - object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8)); + object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VSHADERDATA8)); IDirect3DVertexShaderImpl_ParseProgram(object, pFunction); @@ -839,6 +841,458 @@ HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl* } +/********************************************************************************************************************************************** + ********************************************************************************************************************************************** + ********************************************************************************************************************************************** + ********************************************************************************************************************************************** + **********************************************************************************************************************************************/ + +void pshader_texcoord(D3DSHADERVECTOR* d) { +} + +void pshader_texkill(D3DSHADERVECTOR* d) { +} + +void pshader_tex(D3DSHADERVECTOR* d) { +} + +void pshader_texbem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texbeml(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texreg2ar(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texreg2gb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x2pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x2tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x3pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x3diff(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x3spec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { +} + +void pshader_texm3x3vspec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_cnd(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) { +} + +void pshader_def(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) { +} + +void pshader_texreg2rgb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texdp3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x2depth(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texdp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texm3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { +} + +void pshader_texdepth(D3DSHADERVECTOR* d) { +} + +void pshader_cmp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) { +} + +void pshader_bem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) { +} + +static CONST SHADER_OPCODE pshader_ins [] = { + {D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0}, + {D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0}, + {D3DSIO_ADD, "add", 3, vshader_add, 0, 0}, + {D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0}, + {D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0}, + {D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0}, + {D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0}, + {D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0}, + {D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0}, + {D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0}, + {D3DSIO_MIN, "min", 3, vshader_min, 0, 0}, + {D3DSIO_MAX, "max", 3, vshader_max, 0, 0}, + {D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0}, + {D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0}, + {D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0}, + {D3DSIO_LOG, "log", 2, vshader_log, 0, 0}, + {D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0}, + {D3DSIO_DST, "dst", 3, vshader_dst, 0, 0}, + {D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0}, + {D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0}, + {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0}, + {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0}, + {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0}, + {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0}, + {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0}, + + {D3DSIO_TEXCOORD, "texcoord", 1, pshader_texcoord, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXKILL, "texkill", 1, pshader_texkill, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEX, "tex", 1, pshader_tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)}, + {D3DSIO_TEXBEM, "texbem", 2, pshader_texbem, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXBEML, "texbeml", 2, pshader_texbeml, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXREG2AR, "texreg2ar", 2, pshader_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXREG2GB, "texreg2gb", 2, pshader_texreg2gb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, pshader_texm3x2pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, pshader_texm3x2tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, pshader_texm3x3pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, pshader_texm3x3tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, pshader_texm3x3diff, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)}, + {D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, pshader_texm3x3spec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, pshader_texm3x3vspec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)}, + + {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0}, + {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0}, + + {D3DSIO_CND, "cnd", 4, pshader_cnd, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)}, + {D3DSIO_DEF, "def", 5, pshader_def, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)}, + {D3DSIO_TEXREG2RGB, "texbreg2rgb", 2, pshader_texreg2rgb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, + + {D3DSIO_TEXDP3TEX, "texdp3tex", 2, pshader_texdp3tex, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, pshader_texm3x2depth, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXDP3, "texdp3", 2, pshader_texdp3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXM3x3, "texm3x3", 2, pshader_texm3x3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)}, + {D3DSIO_TEXDEPTH, "texdepth", 1, pshader_texdepth, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, + {D3DSIO_CMP, "cmp", 4, pshader_cmp, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)}, + {D3DSIO_BEM, "bem", 3, pshader_bem, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)}, + + {0, NULL, 0, NULL} +}; + +inline static const SHADER_OPCODE* pshader_program_get_opcode(const DWORD code) { + DWORD i = 0; + /** TODO: use dichotomic search */ + while (NULL != pshader_ins[i].name) { + if ((code & D3DSI_OPCODE_MASK) == pshader_ins[i].opcode) { + return &pshader_ins[i]; + } + ++i; + } + return NULL; +} + +inline static void pshader_program_dump_opcode(const SHADER_OPCODE* curOpcode, const DWORD code, const DWORD output) { + if (0 != (code & ~D3DSI_OPCODE_MASK)) { + DWORD mask = (code & ~D3DSI_OPCODE_MASK); + switch (mask) { + case 0x40000000: TRACE("+"); break; + default: + TRACE(" unhandled modifier(0x%08lx) ", mask); + } + } + TRACE("%s", curOpcode->name); + /** + * normally this is a destination reg modifier + * but in pixel shaders asm code its specified as: + * dp3_x4 t1.rgba, r1, c1 + * or + * dp3_x2_sat r0, t0_bx2, v0_bx2 + * so for better debbuging i use the same norm + */ + if (0 != (output & D3DSP_DSTSHIFT_MASK)) { + DWORD shift = (output & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT; + if (shift > 0) { + TRACE("_x%u", 1 << shift); + } + } + /** + * TODO: fix the divide shifts: d2, d4, d8 + * so i have to find a sample + */ + if (0 != (output & D3DSP_DSTMOD_MASK)) { + DWORD mask = output & D3DSP_DSTMOD_MASK; + switch (mask) { + case D3DSPDM_SATURATE: TRACE("_sat"); break; + default: + TRACE("_unhandled_modifier(0x%08lx)", mask); + } + } + TRACE(" "); +} + +inline static void pshader_program_dump_param(const DWORD param, int input) { + static const char* rastout_reg_names[] = { "oC0", "oC1", "oC2", "oC3", "oDepth" }; + static const char swizzle_reg_chars[] = "rgba"; + + DWORD reg = param & 0x00001FFF; + DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); + + if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) { + TRACE("-"); + } + + switch (regtype << D3DSP_REGTYPE_SHIFT) { + case D3DSPR_TEMP: + TRACE("R[%lu]", reg); + break; + case D3DSPR_INPUT: + TRACE("V[%lu]", reg); + break; + case D3DSPR_CONST: + TRACE("C[%s%lu]", (reg & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg); + break; + case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */ + TRACE("t[%lu]", reg); + break; + case D3DSPR_RASTOUT: + TRACE("%s", rastout_reg_names[reg]); + break; + case D3DSPR_ATTROUT: + TRACE("oD[%lu]", reg); + break; + case D3DSPR_TEXCRDOUT: + TRACE("oT[%lu]", reg); + break; + default: + break; + } + + if (!input) { + /** operand output */ + /** + * for better debugging traces it's done into opcode dump code + * @see pshader_program_dump_opcode + if (0 != (param & D3DSP_DSTMOD_MASK)) { + DWORD mask = param & D3DSP_DSTMOD_MASK; + switch (mask) { + case D3DSPDM_SATURATE: TRACE("_sat"); break; + default: + TRACE("_unhandled_modifier(0x%08lx)", mask); + } + } + if (0 != (param & D3DSP_DSTSHIFT_MASK)) { + DWORD shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT; + if (shift > 0) { + TRACE("_x%u", 1 << shift); + } + } + */ + if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { + if (param & D3DSP_WRITEMASK_0) TRACE(".r"); + if (param & D3DSP_WRITEMASK_1) TRACE(".g"); + if (param & D3DSP_WRITEMASK_2) TRACE(".b"); + if (param & D3DSP_WRITEMASK_3) TRACE(".a"); + } + } else { + /** operand input */ + DWORD swizzle = (param & D3DSP_SWIZZLE_MASK) >> D3DSP_SWIZZLE_SHIFT; + DWORD swizzle_x = swizzle & 0x03; + DWORD swizzle_y = (swizzle >> 2) & 0x03; + DWORD swizzle_z = (swizzle >> 4) & 0x03; + DWORD swizzle_w = (swizzle >> 6) & 0x03; + /** + * swizzle bits fields: + * WWZZYYXX + */ + if ((D3DSP_NOSWIZZLE >> D3DSP_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ + if (swizzle_x == swizzle_y && + swizzle_x == swizzle_z && + swizzle_x == swizzle_w) { + TRACE(".%c", swizzle_reg_chars[swizzle_x]); + } else { + TRACE(".%c%c%c%c", + swizzle_reg_chars[swizzle_x], + swizzle_reg_chars[swizzle_y], + swizzle_reg_chars[swizzle_z], + swizzle_reg_chars[swizzle_w]); + } + } + if (0 != (param & D3DSP_SRCMOD_MASK)) { + DWORD mask = param & D3DSP_SRCMOD_MASK; + /*TRACE("_modifier(0x%08lx) ", mask);*/ + switch (mask) { + case D3DSPSM_NONE: break; + case D3DSPSM_NEG: break; + case D3DSPSM_BIAS: TRACE("_bias"); break; + case D3DSPSM_BIASNEG: TRACE("_bias"); break; + case D3DSPSM_SIGN: TRACE("_sign"); break; + case D3DSPSM_SIGNNEG: TRACE("_sign"); break; + case D3DSPSM_COMP: TRACE("_comp"); break; + case D3DSPSM_X2: TRACE("_x2"); break; + case D3DSPSM_X2NEG: TRACE("_bx2"); break; + case D3DSPSM_DZ: TRACE("_dz"); break; + case D3DSPSM_DW: TRACE("_dw"); break; + default: + TRACE("_unknown(0x%08lx)", mask); + } + } + } +} + +inline static BOOL pshader_is_version_token(DWORD token) { + return 0xFFFF0000 == (token & 0xFFFF0000); +} + +inline static BOOL pshader_is_comment_token(DWORD token) { + return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK); +} + + + +/** + * Pixel Shaders + * + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader1_X/modifiers/sourceregistermodifiers.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader2_0/Registers/Registers.asp + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/IDirect3DPixelShader9/_IDirect3DPixelShader9.asp + * + */ +inline static VOID IDirect3DPixelShaderImpl_ParseProgram(IDirect3DPixelShaderImpl* pshader, CONST DWORD* pFunction) { + const DWORD* pToken = pFunction; + const SHADER_OPCODE* curOpcode = NULL; + DWORD code; + DWORD len = 0; + DWORD i; + + if (NULL != pToken) { + while (D3DPS_END() != *pToken) { + if (pshader_is_version_token(*pToken)) { /** version */ + TRACE("ps.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); + ++pToken; + ++len; + continue; + } + if (pshader_is_comment_token(*pToken)) { /** comment */ + DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; + ++pToken; + /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ + pToken += comment_len; + len += comment_len + 1; + continue; + } + code = *pToken; + curOpcode = pshader_program_get_opcode(code); + ++pToken; + ++len; + if (NULL == curOpcode) { + /* unkown current opcode ... */ + while (*pToken & 0x80000000) { + TRACE("unrecognized opcode: %08lx\n", *pToken); + ++pToken; + ++len; + } + } else { + TRACE(" "); + pshader_program_dump_opcode(curOpcode, code, *pToken); + if (curOpcode->num_params > 0) { + pshader_program_dump_param(*pToken, 0); + ++pToken; + ++len; + for (i = 1; i < curOpcode->num_params; ++i) { + TRACE(", "); + if (D3DSIO_DEF != code) { + pshader_program_dump_param(*pToken, 1); + } else { + TRACE("%f", *((float*) pToken)); + } + ++pToken; + ++len; + } + } + TRACE("\n"); + } + pshader->functionLength = (len + 1) * sizeof(DWORD); + } + } else { + pshader->functionLength = 1; /* no Function defined use fixed function vertex processing */ + } + if (NULL != pFunction) { + pshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pshader->functionLength); + memcpy(pshader->function, pFunction, pshader->functionLength); + } else { + pshader->function = NULL; + } +} + +HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader) { + IDirect3DPixelShaderImpl* object; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl)); + if (NULL == object) { + *ppPixelShader = NULL; + return D3DERR_OUTOFVIDEOMEMORY; + } + /*object->lpVtbl = &Direct3DPixelShader9_Vtbl;*/ + object->device = This; + object->ref = 1; + + object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PSHADERDATA8)); + + IDirect3DPixelShaderImpl_ParseProgram(object, pFunction); + + *ppPixelShader = object; + return D3D_OK; +} + +HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData) { + if (NULL == pData) { + *pSizeOfData = This->functionLength; + return D3D_OK; + } + if (*pSizeOfData < This->functionLength) { + *pSizeOfData = This->functionLength; + return D3DERR_MOREDATA; + } + if (NULL == This->function) { /* no function defined */ + TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData); + (*(DWORD **) pData) = NULL; + } else { + TRACE("(%p) : GetFunction copying to %p\n", This, pData); + memcpy(pData, This->function, This->functionLength); + } + return D3D_OK; +} + +HRESULT WINAPI IDirect3DPixelShaderImpl_SetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) { + if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { + return D3DERR_INVALIDCALL; + } + if (NULL == This->data) { /* temporary while datas not supported */ + FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); + return D3DERR_INVALIDCALL; + } + memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT)); + return D3D_OK; +} + +HRESULT WINAPI IDirect3DPixelShaderImpl_GetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) { + if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) { + return D3DERR_INVALIDCALL; + } + if (NULL == This->data) { /* temporary while datas not supported */ + return D3DERR_INVALIDCALL; + } + memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT)); + return D3D_OK; +} + + +/********************************************************************************************************************************************** + ********************************************************************************************************************************************** + ********************************************************************************************************************************************** + ********************************************************************************************************************************************** + **********************************************************************************************************************************************/ + /*********************************************************************** * ValidateVertexShader (D3D8.@) */ @@ -850,7 +1304,7 @@ BOOL WINAPI ValidateVertexShader(LPVOID what, LPVOID toto) { /*********************************************************************** * ValidatePixelShader (D3D8.@) */ -BOOL WINAPI ValidatePixelShader(LPVOID what) { - FIXME("(void): stub: %p\n", what); +BOOL WINAPI ValidatePixelShader(LPVOID what, LPVOID toto) { + FIXME("(void): stub: %p %p\n", what, toto); return TRUE; }