-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 second patch from the split and independent from the the patch2 Changelog: - Resend of my last vertex shader patch + improvements - move input and output data in VertexShader struct - better traces - specific input data filling function for vertex shaders using vertex shader declaration (and not FVF ... maybe FVF will return for fast path with simples vertex shader declarations) - huge vertex shader fixes: - add and fix many vs (1.0->2.0) used opcodes in complex shaders - improvements to programs parser: parse comments, version, .. - add a vertex shader input filler function (parsing vertex shader declaration): almost complete - comments most of the traces (else flood ...) - add more urls in comments - indent, cleanups This patch have a warning because of empty macro (needed for GL extension work) l'll fix it later Raphael -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQE+IEAUp7NA3AmQTU4RAjteAJ0UPH7qRUlRL7uf53I4stGIiSAhngCZAcWj CJ7Xz9LakW/mmtesUrvg4qI= =Bquw -----END PGP SIGNATURE-----
Index: dlls/d3d8/d3d8_main.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/d3d8_main.c,v retrieving revision 1.6 diff -u -r1.6 d3d8_main.c --- dlls/d3d8/d3d8_main.c 17 Dec 2002 01:15:16 -0000 1.6 +++ dlls/d3d8/d3d8_main.c 11 Jan 2003 15:00:02 -0000 @@ -22,6 +22,9 @@ #include "winuser.h" #include "wine/debug.h" +#include "config.h" +#include "x11drv.h" + #include "d3d8.h" #include "d3d8_private.h" Index: dlls/d3d8/d3d8_private.h =================================================================== RCS file: /home/wine/wine/dlls/d3d8/d3d8_private.h,v retrieving revision 1.10 diff -u -r1.10 d3d8_private.h --- dlls/d3d8/d3d8_private.h 2 Jan 2003 17:59:02 -0000 1.10 +++ dlls/d3d8/d3d8_private.h 11 Jan 2003 15:00:43 -0000 @@ -42,6 +42,8 @@ /* X11 locking */ +#include "x11drv.h" + extern void (*wine_tsx11_lock_ptr)(void); extern void (*wine_tsx11_unlock_ptr)(void); @@ -98,10 +100,10 @@ typedef struct STATEBLOCK { - D3DSTATEBLOCKTYPE blockType; + D3DSTATEBLOCKTYPE blockType; - SAVEDSTATES Changed; - SAVEDSTATES Set; + SAVEDSTATES Changed; + SAVEDSTATES Set; /* Light Enable */ BOOL lightEnable[MAX_ACTIVE_LIGHTS]; @@ -150,6 +152,10 @@ /* TODO: Vertex Shader Constant */ + /* Indexed Vertex Blending */ + D3DVERTEXBLENDFLAGS vertex_blend; + FLOAT tween_factor; + } STATEBLOCK; typedef struct D3DSHADERVECTOR { @@ -176,6 +182,20 @@ UINT codeLength; } SHADERDATA8; +/** temporary here waiting for buffer code */ +typedef struct VSHADERINPUTDATA8 { + D3DSHADERVECTOR V[16]; +} VSHADERINPUTDATA8; + +/** temporary here waiting for buffer code */ +typedef struct VSHADEROUTPUTDATA8 { + D3DSHADERVECTOR oPos; + D3DSHADERVECTOR oD[2]; + D3DSHADERVECTOR oT[4]; + D3DSHADERVECTOR oFog; + D3DSHADERVECTOR oPts; +} VSHADEROUTPUTDATA8; + typedef struct VERTEXSHADER8 { /* TODO: Vertex Shader */ DWORD* decl; DWORD* function; @@ -186,6 +206,8 @@ DWORD version; /* run time datas */ SHADERDATA8* data; + VSHADERINPUTDATA8 input; + VSHADEROUTPUTDATA8 output; } VERTEXSHADER8; typedef struct PIXELSHADER8 { /* TODO: Pixel Shader */ @@ -196,20 +218,6 @@ SHADERDATA8* data; } PIXELSHADER8; -/** temporary here waiting for buffer code */ -typedef struct VSHADERINPUTDATA8 { - D3DSHADERVECTOR V[16]; -} VSHADERINPUTDATA8; - -/** temporary here waiting for buffer code */ -typedef struct VSHADEROUTPUTDATA8 { - D3DSHADERVECTOR oPos; - D3DSHADERVECTOR oD[2]; - D3DSHADERVECTOR oT[4]; - D3DSHADERVECTOR oFog; - D3DSHADERVECTOR oPts; -} VSHADEROUTPUTDATA8; - /* * External prototypes */ @@ -229,6 +237,29 @@ } \ } +#define checkGLSupport(ExtName) FALSE/*(TRUE == This->direct3d8->glInfo.supported[ExtName])*/ +#define GLExtCall(FuncName) /*(This->direct3d8->glInfo.FuncName)*/ + + +#define D3DCOLOR_R(dw) (((float) (((dw) >> 16) & 0xFF)) / 255.0f) +#define D3DCOLOR_G(dw) (((float) (((dw) >> 8) & 0xFF)) / 255.0f) +#define D3DCOLOR_B(dw) (((float) (((dw) >> 0) & 0xFF)) / 255.0f) +#define D3DCOLOR_A(dw) (((float) (((dw) >> 24) & 0xFF)) / 255.0f) + +#define D3DCOLORTOCOLORVALUE(dw, col) \ + (col).r = D3DCOLOR_R(dw); \ + (col).g = D3DCOLOR_G(dw); \ + (col).b = D3DCOLOR_B(dw); \ + (col).a = D3DCOLOR_A(dw); + +#define D3DCOLORTOVECTOR4(dw, vec) \ + (vec).x = D3DCOLOR_R(dw); \ + (vec).y = D3DCOLOR_G(dw); \ + (vec).z = D3DCOLOR_B(dw); \ + (vec).w = D3DCOLOR_A(dw); + + + /* =========================================================================== The interfactes themselves =========================================================================== */ @@ -929,5 +960,6 @@ DWORD vshader_decl_parse(VERTEXSHADER8* vshader); DWORD vshader_program_parse(VERTEXSHADER8* vshader); BOOL vshader_program_execute_SW(VERTEXSHADER8* vshader, VSHADERINPUTDATA8* input, VSHADEROUTPUTDATA8* output); +VOID vshader_fill_input(VERTEXSHADER8* vshader, IDirect3DDevice8Impl* device, const void* vertexFirstStream, DWORD StartVertexIndex, DWORD idxDecal); #endif /* __WINE_D3DX8_PRIVATE_H */ Index: dlls/d3d8/device.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/device.c,v retrieving revision 1.23 diff -u -r1.23 device.c --- dlls/d3d8/device.c 9 Jan 2003 06:02:39 -0000 1.23 +++ dlls/d3d8/device.c 11 Jan 2003 15:01:10 -0000 @@ -106,7 +106,6 @@ int NumVertexes = NumPrimitives; VERTEXSHADER8* vertex_shader = NULL; - VSHADERINPUTDATA8 vertex_shader_input; BOOL useVertexShaderFunction = FALSE; ICOM_THIS(IDirect3DDevice8Impl,iface); @@ -127,7 +126,7 @@ } fvf = (D3DFORMAT) vertex_shader->fvf; TRACE("vertex shader declared FVF: %lx\n", vertex_shader->fvf); - memset(&vertex_shader_input, 0, sizeof(VSHADERINPUTDATA8)); + memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA8)); } { @@ -302,22 +301,11 @@ curPos = curPos + sizeof(float); VTRACE(("x,y,z=%f,%f,%f\n", x,y,z)); - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_POSITION].x = x; - vertex_shader_input.V[D3DVSDE_POSITION].y = y; - vertex_shader_input.V[D3DVSDE_POSITION].z = z; - vertex_shader_input.V[D3DVSDE_POSITION].w = 1.0f; - } - /* RHW follows, only if transformed */ if (isRHW) { rhw = *(float *)curPos; curPos = curPos + sizeof(float); VTRACE(("rhw=%f\n", rhw)); - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_POSITION].w = rhw; - } } /* Blending data */ @@ -335,20 +323,6 @@ skippedBlendLastUByte4 = *(DWORD*)curPos; curPos = curPos + sizeof(DWORD); } - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].x = skippedBlend.x; - vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].y = skippedBlend.y; - vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].z = skippedBlend.z; - vertex_shader_input.V[D3DVSDE_BLENDWEIGHT].w = skippedBlend.w; - - if (isLastUByte4) { - vertex_shader_input.V[D3DVSDE_BLENDINDICES].x = (float) skippedBlendLastUByte4; - vertex_shader_input.V[D3DVSDE_BLENDINDICES].y = (float) skippedBlendLastUByte4; - vertex_shader_input.V[D3DVSDE_BLENDINDICES].z = (float) skippedBlendLastUByte4; - vertex_shader_input.V[D3DVSDE_BLENDINDICES].w = (float) skippedBlendLastUByte4; - } - } } /* Vertex Normal Data (untransformed only) */ @@ -360,52 +334,24 @@ nz = *(float *)curPos; curPos = curPos + sizeof(float); VTRACE(("nx,ny,nz=%f,%f,%f\n", nx,ny,nz)); - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_NORMAL].x = nx; - vertex_shader_input.V[D3DVSDE_NORMAL].y = ny; - vertex_shader_input.V[D3DVSDE_NORMAL].z = nz; - vertex_shader_input.V[D3DVSDE_NORMAL].w = 1.0f; - } } if (isPtSize) { ptSize = *(float *)curPos; VTRACE(("ptSize=%f\n", ptSize)); curPos = curPos + sizeof(float); - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_PSIZE].x = ptSize; - vertex_shader_input.V[D3DVSDE_PSIZE].y = 0.0f; - vertex_shader_input.V[D3DVSDE_PSIZE].z = 0.0f; - vertex_shader_input.V[D3DVSDE_PSIZE].w = 1.0f; - } } if (isDiffuse) { diffuseColor = *(DWORD *)curPos; VTRACE(("diffuseColor=%lx\n", diffuseColor)); curPos = curPos + sizeof(DWORD); - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_DIFFUSE].x = (float) (((diffuseColor >> 16) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_DIFFUSE].y = (float) (((diffuseColor >> 8) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_DIFFUSE].z = (float) (((diffuseColor >> 0) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_DIFFUSE].w = (float) (((diffuseColor >> 24) & 0xFF) / 255.0f); - } } if (isSpecular) { specularColor = *(DWORD *)curPos; VTRACE(("specularColor=%lx\n", specularColor)); curPos = curPos + sizeof(DWORD); - - if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_SPECULAR].x = (float) (((specularColor >> 16) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_SPECULAR].y = (float) (((specularColor >> 8) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_SPECULAR].z = (float) (((specularColor >> 0) & 0xFF) / 255.0f); - vertex_shader_input.V[D3DVSDE_SPECULAR].w = (float) (((specularColor >> 24) & 0xFF) / 255.0f); - } } /* ToDo: Texture coords */ @@ -432,10 +378,7 @@ VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t)); if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].x = s; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].y = t; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].z = 0.0f; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].w = 1.0f; + /* Nothing to do */ } else { if (This->isMultiTexture) { glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); @@ -455,10 +398,7 @@ VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r)); if (TRUE == useVertexShaderFunction) { - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].x = s; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].y = t; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].z = r; - vertex_shader_input.V[D3DVSDE_TEXCOORD0 + textureNo].w = 1.0f; + /* Nothing to do */ } else { if (This->isMultiTexture) { glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); @@ -481,38 +421,53 @@ /** if vertex shader program specified ... using it */ if (TRUE == useVertexShaderFunction) { - VSHADEROUTPUTDATA8 vs_o; - memset(&vs_o, 0, sizeof(VSHADEROUTPUTDATA8)); - vshader_program_execute_SW(vertex_shader, &vertex_shader_input, &vs_o); + + /** + * this code must become the really + * vs input params init + * + * because its possible to use input registers for anything + * and some samples use registers for other things than they are + * declared + */ + + /** + * no really valid declaration, user defined input register use + * so fill input registers as described in vertex shader declaration + */ + vshader_fill_input(vertex_shader, This, vertexBufData, StartVertexIndex, + (!isIndexed) ? (vx_index * skip) : + (idxBytes == 2) ? ((pIdxBufS[StartIdx + vx_index]) * skip) : + ((pIdxBufL[StartIdx + vx_index]) * skip)); + + memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA8)); + vshader_program_execute_SW(vertex_shader, &vertex_shader->input, &vertex_shader->output); /* - TRACE_VECTOR(vs_o.oPos); - TRACE_VECTOR(vs_o.oD[0]); - TRACE_VECTOR(vs_o.oT[0]); - TRACE_VECTOR(vs_o.oT[1]); + TRACE_VECTOR(vertex_shader->output.oPos); + TRACE_VECTOR(vertex_shader->output.oD[0]); + TRACE_VECTOR(vertex_shader->output.oD[1]); + TRACE_VECTOR(vertex_shader->output.oT[0]); + TRACE_VECTOR(vertex_shader->output.oT[1]); */ - x = vs_o.oPos.x; - y = vs_o.oPos.y; - z = vs_o.oPos.z; + x = vertex_shader->output.oPos.x; + y = vertex_shader->output.oPos.y; + z = vertex_shader->output.oPos.z; + + if (1.0f != vertex_shader->output.oPos.w || isRHW) { + rhw = vertex_shader->output.oPos.w; + } + /*diffuseColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[0]);*/ + glColor4fv((float*) &vertex_shader->output.oD[0]); + + /* Requires secondary color extensions to compile... */ + if (checkGLSupport(EXT_SECONDARY_COLOR)) { + /*specularColor = D3DCOLOR_COLORVALUE(vertex_shader->output.oD[1]);*/ + GLExtCall(glSecondaryColor3fvEXT)((float*) &vertex_shader->output.oD[1]); + /*checkGLcall("glSecondaryColor3fvEXT");*/ + } - if (1.0f != vs_o.oPos.w || isRHW) { - rhw = vs_o.oPos.w; - } - /*TRACE_VECTOR(vs_o.oPos);*/ - if (isDiffuse) { - /*diffuseColor = D3DCOLOR_COLORVALUE(vs_o.oD[0].x, vs_o.oD[0].y, vs_o.oD[0].z, vs_o.oD[0].w);*/ - /*TRACE_VECTOR(vs_o.oD[0]);*/ - /*glColor4f(vs_o.oD[0].x, vs_o.oD[0].y, vs_o.oD[0].z, vs_o.oD[0].w); */ - glMaterialfv(GL_FRONT, GL_DIFFUSE, (float*) &vs_o.oD[0]); - checkGLcall("glMaterialfv"); - } - if (isSpecular) { - /*specularColor = D3DCOLOR_COLORVALUE(vs_o.oD[1].x, vs_o.oD[1].y, vs_o.oD[1].z, vs_o.oD[1].w);*/ - /*TRACE_VECTOR(vs_o.oD[1]);*/ - glMaterialfv(GL_FRONT, GL_SPECULAR, (float*) &vs_o.oD[1]); - checkGLcall("glMaterialfv"); - } - /** reupdate textures coords binding using vs_o.oT[0->3] */ - for (textureNo = 0; textureNo < 4/*min(numTextures, 4)*/; ++textureNo) { + /** reupdate textures coords binding using vertex_shader->output.oT[0->3] */ + for (textureNo = 0; textureNo < 4; ++textureNo) { float s, t, r, q; if (!(This->isMultiTexture) && textureNo > 0) { @@ -523,31 +478,31 @@ if (This->StateBlock.textures[textureNo] != NULL) { switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) { case D3DRTYPE_TEXTURE: - /*TRACE_VECTOR(vs_o.oT[textureNo]);*/ - s = vs_o.oT[textureNo].x; - t = vs_o.oT[textureNo].y; - VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s,t)); + /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/ + s = vertex_shader->output.oT[textureNo].x; + t = vertex_shader->output.oT[textureNo].y; + VTRACE(("tex:%d, s,t=%f,%f\n", textureNo, s, t)); if (This->isMultiTexture) { glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); - checkGLcall("glMultiTexCoord2fARB"); + /*checkGLcall("glMultiTexCoord2fARB");*/ } else { glTexCoord2f(s, t); - checkGLcall("gTexCoord2f"); + /*checkGLcall("gTexCoord2f");*/ } break; case D3DRTYPE_VOLUMETEXTURE: - /*TRACE_VECTOR(vs_o.oT[textureNo]);*/ - s = vs_o.oT[textureNo].x; - t = vs_o.oT[textureNo].y; - r = vs_o.oT[textureNo].z; - VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r)); + /*TRACE_VECTOR(vertex_shader->output.oT[textureNo]);*/ + s = vertex_shader->output.oT[textureNo].x; + t = vertex_shader->output.oT[textureNo].y; + r = vertex_shader->output.oT[textureNo].z; + VTRACE(("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s, t, r)); if (This->isMultiTexture) { glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); - checkGLcall("glMultiTexCoord2fARB"); + /*checkGLcall("glMultiTexCoord2fARB");*/ } else { glTexCoord3f(s, t, r); - checkGLcall("gTexCoord3f"); + /*checkGLcall("gTexCoord3f");*/ } break; @@ -562,11 +517,11 @@ if (1.0f == rhw || rhw < 0.01f) { VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); glVertex3f(x, y, z); - checkGLcall("glVertex3f"); + /*checkGLcall("glVertex3f");*/ } else { VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw)); glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw); - checkGLcall("glVertex4f"); + /*checkGLcall("glVertex4f");*/ } } else { /** Index: dlls/d3d8/shader.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/shader.c,v retrieving revision 1.4 diff -u -r1.4 shader.c --- dlls/d3d8/shader.c 2 Jan 2003 19:28:09 -0000 1.4 +++ dlls/d3d8/shader.c 11 Jan 2003 15:03:24 -0000 @@ -26,6 +26,9 @@ #include <math.h> +#include "config.h" +#include "x11drv.h" + #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); @@ -54,6 +57,12 @@ * * FVF * http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp + * + * NVIDIA: DX8 Vertex Shader to NV Vertex Program + * http://developer.nvidia.com/view.asp?IO=vstovp + * + * NVIDIA: Memory Management with VAR + * http://developer.nvidia.com/view.asp?IO=var_memory_management */ typedef void (*shader_fct_t)(); @@ -137,10 +146,14 @@ void vshader_expp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { float tmp_f = floorf(s0->w); - d->x = powf(2.0f, tmp_f); - d->y = s0->w - tmp_f; - d->z = powf(2.0f, s0->w); - d->w = 1.0f; + DWORD tmp_d = 0; + tmp_f = powf(2.0f, s0->w); + tmp_d = *((DWORD*) &tmp_f) & 0xFFFFFF00; + + d->x = powf(2.0f, tmp_f); + d->y = s0->w - tmp_f; + d->z = *((float*) &tmp_d); + d->w = 1.0f; /* DPRINTF("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", @@ -245,27 +258,123 @@ } /** + * Version 1.1 specific + */ + +void vshader_exp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { + d->x = d->y = d->z = d->w = powf(2.0f, s0->w); +} + +void vshader_log(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { + float tmp_f = fabsf(s0->w); + d->x = d->y = d->z = d->w = (0.0f != tmp_f) ? logf(tmp_f) / logf(2.0f) : -HUGE; +} + +void vshader_frc(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) { + d->x = s0->x - floorf(s0->x); + d->y = s0->y - floorf(s0->y); + d->z = 0.0f; + d->w = 1.0f; +} + +typedef FLOAT D3DMATRIX44[4][4]; +typedef FLOAT D3DMATRIX43[4][3]; +typedef FLOAT D3DMATRIX34[4][4]; +typedef FLOAT D3DMATRIX33[4][3]; +typedef FLOAT D3DMATRIX32[4][2]; + +void vshader_m4x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, /*D3DSHADERVECTOR* mat1*/ D3DMATRIX44 mat) { + /* + * BuGGY CODE: here only if cast not work for copy/paste + D3DSHADERVECTOR* mat2 = mat1 + 1; + D3DSHADERVECTOR* mat3 = mat1 + 2; + D3DSHADERVECTOR* mat4 = mat1 + 3; + d->x = mat1->x * s0->x + mat2->x * s0->y + mat3->x * s0->z + mat4->x * s0->w; + d->y = mat1->y * s0->x + mat2->y * s0->y + mat3->y * s0->z + mat4->y * s0->w; + d->z = mat1->z * s0->x + mat2->z * s0->y + mat3->z * s0->z + mat4->z * s0->w; + d->w = mat1->w * s0->x + mat2->w * s0->y + mat3->w * s0->z + mat4->w * s0->w; + */ + d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w; + d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w; + d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w; + d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z + mat[3][3] * s0->w; +} + +void vshader_m4x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX43 mat) { + FIXME("check\n"); + d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w; + d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w; + d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w; + d->w = 1.0f; +} + +void vshader_m3x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX34 mat) { + FIXME("check\n"); + d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z; + d->y = mat[2][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z; + d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z; + d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z; +} + +void vshader_m3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX33 mat) { + FIXME("check\n"); + d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[2][2] * s0->z; + d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[2][2] * s0->z; + d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z; + d->w = 1.0f; +} + +void vshader_m3x2(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX32 mat) { + FIXME("check\n"); + d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z; + d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z; + d->z = 0.0f; + d->w = 1.0f; +} + +/** + * Version 2.0 specific + */ +void vshader_lrp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) { + d->x = s0->x * (s1->x - s2->x) + s2->x; + d->y = s0->y * (s1->y - s2->y) + s2->y; + d->z = s0->z * (s1->z - s2->z) + s2->z; + d->w = s0->w * (s1->w - s2->w) + s2->x; +} + +/** * 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_MAX, "max", 3, vshader_max}, - {D3DSIO_MIN, "min", 3, vshader_min}, - {D3DSIO_SGE, "sge", 3, vshader_sge}, - {D3DSIO_SLT, "slt", 3, vshader_slt}, {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_MAD, "mad", 4, vshader_mad}, + {D3DSIO_RSQ, "rsq", 2, vshader_rsq}, {D3DSIO_DP3, "dp3", 3, vshader_dp3}, {D3DSIO_DP4, "dp4", 3, vshader_dp4}, - {D3DSIO_RSQ, "rsq", 2, vshader_rsq}, - {D3DSIO_DST, "dst", 3, vshader_dst}, + {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}, + /** FIXME: use direct acces so add the others opcodes as stubs */ {D3DSIO_EXPP, "expp", 2, vshader_expp}, {D3DSIO_LOGP, "logp", 2, vshader_logp}, - {D3DSIO_NOP, "nop", 0, vshader_nop}, + {0, NULL, 0, NULL} }; @@ -352,6 +461,14 @@ } } +inline static BOOL vshader_is_version_token(DWORD token) { + return 0xFFFE0000 == (token & 0xFFFE0000); +} + +inline static BOOL vshader_is_comment_token(DWORD token) { + return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK); +} + /** * Function parser ... */ @@ -363,13 +480,27 @@ if (NULL != pToken) { while (D3DVS_END() != *pToken) { + if (vshader_is_version_token(*pToken)) { /** version */ + DPRINTF("vs.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F)); + ++pToken; + ++len; + continue; + } + if (vshader_is_comment_token(*pToken)) { /** comment */ + DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; + ++pToken; + /*DPRINTF("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/ + pToken += comment_len; + len += comment_len + 1; + continue; + } curOpcode = vshader_program_get_opcode(*pToken); ++pToken; ++len; if (NULL == curOpcode) { /* unkown current opcode ... */ while (*pToken & 0x80000000) { - DPRINTF("unrecognized opcode: %08lX\n", *pToken); + DPRINTF("unrecognized opcode: %08lx\n", *pToken); ++pToken; ++len; } @@ -426,7 +557,9 @@ D3DSHADERVECTOR* p_send[4]; DWORD i; + /** init temporary register */ memset(R, 0, 12 * sizeof(D3DSHADERVECTOR)); + /* vshader_program_parse(vshader); */ /* TRACE_VECTOR(vshader->data->C[0]); @@ -449,13 +582,29 @@ /* the first dword is the version tag */ /* TODO: parse it */ + if (vshader_is_version_token(*pToken)) { /** version */ + ++pToken; + } while (D3DVS_END() != *pToken) { + if (vshader_is_comment_token(*pToken)) { /** comment */ + DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT; + ++pToken; + pToken += comment_len; + continue ; + } curOpcode = vshader_program_get_opcode(*pToken); ++pToken; if (NULL == curOpcode) { + i = 0; /* unkown current opcode ... */ while (*pToken & 0x80000000) { - DPRINTF("unrecognized opcode: pos=%d token=%08lX\n", pToken - vshader->function, *pToken); + if (i == 0) { + DPRINTF("unrecognized opcode: pos=%d token=%08lX\n", (pToken - 1) - vshader->function, *(pToken - 1)); + } + DPRINTF("unrecognized opcode param: pos=%d token=%08lX what=", pToken - vshader->function, *pToken); + vshader_program_dump_param(*pToken, i); + DPRINTF("\n"); + ++i; ++pToken; } /*return FALSE;*/ @@ -561,6 +710,9 @@ case 4: curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3]); break; + case 5: + curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3], p_send[4]); + break; default: ERR("%s too many params: %u\n", curOpcode->name, curOpcode->num_params); } @@ -678,6 +830,7 @@ const DWORD* pToken = vshader->decl; DWORD fvf = 0; DWORD len = 0; + DWORD stream = 0; DWORD token; DWORD tokenlen; DWORD tokentype; @@ -686,12 +839,19 @@ while (D3DVSD_END() != *pToken) { token = *pToken; tokenlen = vshader_decl_parse_token(pToken); - tokentype = ((*pToken & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); + tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); /** FVF generation block */ - if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { + if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) { + /** + * how really works streams, + * in DolphinVS dx8 dsk sample they seems to decal reg numbers !!! + */ + stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT); + + } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); - DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); + DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT) - stream; switch (reg) { case D3DVSDE_POSITION: @@ -699,7 +859,7 @@ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break; case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -710,7 +870,7 @@ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break; case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -718,7 +878,7 @@ switch (type) { case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -726,7 +886,7 @@ switch (type) { case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -734,7 +894,7 @@ switch (type) { case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -742,7 +902,7 @@ switch (type) { case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -750,7 +910,7 @@ switch (type) { case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break; default: /** errooooorr what to do ? */ - ERR("Error in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %lu\n", type); + ERR("Error in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } break; @@ -787,18 +947,211 @@ return len * sizeof(DWORD); } + +void vshader_fill_input(VERTEXSHADER8* vshader, + IDirect3DDevice8Impl* device, + const void* vertexFirstStream, + DWORD StartVertexIndex, + DWORD idxDecal) { + /** parser data */ + const DWORD* pToken = vshader->decl; + DWORD stream = 0; + DWORD token; + /*DWORD tokenlen;*/ + DWORD tokentype; + /** for input readers */ + const void* curPos = NULL; + FLOAT x, y, z, w; + SHORT u, v, r, t; + DWORD dw; + + /*TRACE("(%p) - device:%p - stream:%p, startIdx=%lu, idxDecal=%lu\n", vshader, device, vertexFirstStream, StartVertexIndex, idxDecal);*/ + 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; + const void* startVtx = NULL; + int skip = 0; + + ++pToken; + /** + * how really works streams, + * in DolphinVS dx8 dsk sample use it !!! + */ + stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT); + + if (0 == stream) { + skip = device->StateBlock.stream_stride[0]; + startVtx = vertexFirstStream + (StartVertexIndex * skip); + curPos = startVtx + idxDecal; + /*TRACE(" using stream[%lu] with %lu decal => curPos %p\n", stream, idxDecal, curPos);*/ + } else { + skip = device->StateBlock.stream_stride[stream]; + pVB = device->StateBlock.stream_source[stream]; + + if (NULL == pVB) { + ERR("using unitialised stream[%lu]\n", stream); + return ; + } else { + startVtx = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (StartVertexIndex * skip); + /** do we need to decal if we use idxBuffer */ + curPos = startVtx + idxDecal; + /*TRACE(" using stream[%lu] with %lu decal\n", stream, idxDecal);*/ + } + } + } 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) { + 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); + 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; + + switch (type) { + case D3DVSDT_FLOAT1: + x = *(float*) curPos; + curPos = curPos + sizeof(float); + /**/ + vshader->input.V[reg].x = x; + vshader->input.V[reg].y = 0.0f; + vshader->input.V[reg].z = 0.0f; + vshader->input.V[reg].w = 1.0f; + break; + + case D3DVSDT_FLOAT2: + x = *(float*) curPos; + curPos = curPos + sizeof(float); + y = *(float*) curPos; + curPos = curPos + sizeof(float); + /**/ + vshader->input.V[reg].x = x; + vshader->input.V[reg].y = y; + vshader->input.V[reg].z = 0.0f; + vshader->input.V[reg].w = 1.0f; + break; + + case D3DVSDT_FLOAT3: + x = *(float*) curPos; + curPos = curPos + sizeof(float); + y = *(float*) curPos; + curPos = curPos + sizeof(float); + z = *(float*) curPos; + curPos = curPos + sizeof(float); + /**/ + vshader->input.V[reg].x = x; + vshader->input.V[reg].y = y; + vshader->input.V[reg].z = z; + vshader->input.V[reg].w = 1.0f; + break; + + case D3DVSDT_FLOAT4: + x = *(float*) curPos; + curPos = curPos + sizeof(float); + y = *(float*) curPos; + curPos = curPos + sizeof(float); + z = *(float*) curPos; + curPos = curPos + sizeof(float); + w = *(float*) curPos; + curPos = curPos + sizeof(float); + /**/ + vshader->input.V[reg].x = x; + vshader->input.V[reg].y = y; + vshader->input.V[reg].z = z; + vshader->input.V[reg].w = w; + break; + + case D3DVSDT_D3DCOLOR: + dw = *(DWORD*) curPos; + curPos = curPos + sizeof(DWORD); + /**/ + vshader->input.V[reg].x = (float) (((dw >> 16) & 0xFF) / 255.0f); + vshader->input.V[reg].y = (float) (((dw >> 8) & 0xFF) / 255.0f); + vshader->input.V[reg].z = (float) (((dw >> 0) & 0xFF) / 255.0f); + vshader->input.V[reg].w = (float) (((dw >> 24) & 0xFF) / 255.0f); + break; + + case D3DVSDT_SHORT2: + u = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + v = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + /**/ + vshader->input.V[reg].x = (float) u; + vshader->input.V[reg].y = (float) v; + vshader->input.V[reg].z = 0.0f; + vshader->input.V[reg].w = 1.0f; + break; + + case D3DVSDT_SHORT4: + u = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + v = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + t = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + t = *(SHORT*) curPos; + curPos = curPos + sizeof(SHORT); + /**/ + vshader->input.V[reg].x = (float) u; + vshader->input.V[reg].y = (float) v; + vshader->input.V[reg].z = (float) r; + vshader->input.V[reg].w = (float) t; + break; + + case D3DVSDT_UBYTE4: + dw = *(DWORD*) curPos; + curPos = curPos + sizeof(DWORD); + /**/ + vshader->input.V[reg].x = (float) ((dw & 0x000F) >> 0); + vshader->input.V[reg].y = (float) ((dw & 0x00F0) >> 8); + vshader->input.V[reg].z = (float) ((dw & 0x0F00) >> 16); + vshader->input.V[reg].w = (float) ((dw & 0xF000) >> 24); + + 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() */ +} + + /*********************************************************************** * ValidateVertexShader (D3D8.@) */ BOOL WINAPI ValidateVertexShader(LPVOID what, LPVOID toto) { - FIXME("(void): stub: %p\n", what); + FIXME("(void): stub: %p %p\n", what, toto); return TRUE; } /*********************************************************************** * ValidatePixelShader (D3D8.@) */ -BOOL WINAPI ValidatePixelShader(LPVOID what, LPVOID toto) { +BOOL WINAPI ValidatePixelShader(LPVOID what) { FIXME("(void): stub: %p\n", what); return TRUE; } +