? tmp.diff Index: d3d8_private.h =================================================================== RCS file: /home/wine/wine/dlls/d3d8/d3d8_private.h,v retrieving revision 1.8 diff -u -r1.8 d3d8_private.h --- d3d8_private.h 18 Dec 2002 05:05:41 -0000 1.8 +++ d3d8_private.h 19 Dec 2002 00:28:25 -0000 @@ -198,6 +198,25 @@ SHADER8Data* data; } PIXELSHADER8; +/** temporary here waiting for buffer code */ +typedef struct vshader_input_data { + /*SHADER8Vector V[16];//0-15*/ + SHADER8Vector V[16]; +} vshader_input_data; + +/** temporary here waiting for buffer code */ +typedef struct vshader_output_data { + SHADER8Vector oPos; + /*SHADER8Vector oD[2];//0-1*/ + SHADER8Vector oD[2]; + /*SHADER8Vector oT[4];//0-3*/ + SHADER8Vector oT[4]; + /*SHADER8Scalar oFog;*/ + /*SHADER8Scalar oPts;*/ + SHADER8Vector oFog; + SHADER8Vector oPts; +} vshader_output_data; + /* * External prototypes */ @@ -912,6 +931,6 @@ */ DWORD vshader_decl_parse(VERTEXSHADER8* vshader); DWORD vshader_program_parse(VERTEXSHADER8* vshader); - +BOOL vshader_program_execute_SW(VERTEXSHADER8* vshader, vshader_input_data* input, vshader_output_data* output); #endif /* __WINE_D3DX8_PRIVATE_H */ Index: device.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/device.c,v retrieving revision 1.16 diff -u -r1.16 device.c --- device.c 18 Dec 2002 05:05:41 -0000 1.16 +++ device.c 19 Dec 2002 00:28:40 -0000 @@ -53,6 +53,11 @@ memcpy(gl_mat, (mat), 16 * sizeof(float)); \ }; +#define VERTEX_SHADER(Handle) \ + ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF]) + +#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w); + /* * Globals */ @@ -68,6 +73,7 @@ 0.0, 0.0, 0.0, 1.0 }; + /* Routine common to the draw primitive and draw indexed primitive routines Doesnt use gl pointer arrays as I dont believe we can support the blending coordinates that way. */ @@ -89,17 +95,38 @@ int vx_index; int NumVertexes = NumPrimitives; + VERTEXSHADER8* vertex_shader = NULL; + vshader_input_data vertex_shader_input; ICOM_THIS(IDirect3DDevice8Impl,iface); /* Dont understand how to handle multiple streams, but if a fixed FVF is passed in rather than a handle, it must use stream 0 */ - + + /* if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) { FIXME("Cant handle created shaders yet\n"); return; - } else { + } else + */ + + if (This->StateBlock.VertexShader > VS_HIGHESTFIXEDFXF) { + vertex_shader = VERTEX_SHADER(This->StateBlock.VertexShader); + if (NULL == vertex_shader) { + ERR("trying to use unitialised vertex shader: %lu\n", This->StateBlock.VertexShader); + return; + } + if (NULL == vertex_shader->function) { + TRACE("vertex shader declared without program, using FVF pure mode\n"); + } + fvf = (D3DFORMAT) vertex_shader->fvf; + TRACE("vertex shader declared FVF: %x\n", vertex_shader->fvf); + memset(&vertex_shader_input, 0, sizeof(vshader_input_data)); + } + + + { int skip = This->StateBlock.stream_stride[0]; BOOL normal; @@ -136,7 +163,7 @@ isPtSize = fvf & D3DFVF_PSIZE; isDiffuse = fvf & D3DFVF_DIFFUSE; isSpecular = fvf & D3DFVF_SPECULAR; - numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; + numTextures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; TRACE("Drawing with FVF = %x, (n?%d, rhw?%d, ptSize(%d), diffuse?%d, specular?%d, numTextures=%d)\n", fvf, normal, isRHW, isPtSize, isDiffuse, isSpecular, numTextures); @@ -155,10 +182,10 @@ double height, width, minZ, maxZ; /* - * Already transformed vertex do not need transform - * matrices. Reset all matrices to identity. - * Leave the default matrix in world mode. - */ + * Already transformed vertex do not need transform + * matrices. Reset all matrices to identity. + * Leave the default matrix in world mode. + */ glMatrixMode(GL_PROJECTION); checkGLcall("glMatrixMode"); glLoadIdentity(); @@ -259,11 +286,22 @@ curPos = curPos + sizeof(float); TRACE("x,y,z=%f,%f,%f\n", x,y,z); + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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); TRACE("rhw=%f\n", rhw); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + vertex_shader_input.V[D3DVSDE_POSITION].w = rhw; + } } @@ -278,71 +316,173 @@ nz = *(float *)curPos; curPos = curPos + sizeof(float); TRACE("nx,ny,nz=%f,%f,%f\n", nx,ny,nz); - } + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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; curPos = curPos + sizeof(float); TRACE("ptSize=%f\n", ptSize); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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; TRACE("diffuseColor=%lx\n", diffuseColor); curPos = curPos + sizeof(DWORD); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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; TRACE("specularColor=%lx\n", specularColor); curPos = curPos + sizeof(DWORD); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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 */ - for (textureNo = 0;textureNoStateBlock.textures[textureNo] != NULL) { - switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) { - case D3DRTYPE_TEXTURE: - s = *(float *)curPos; - curPos = curPos + sizeof(float); - t = *(float *)curPos; - curPos = curPos + sizeof(float); - TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t); - glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); - break; - - case D3DRTYPE_VOLUMETEXTURE: - s = *(float *)curPos; - curPos = curPos + sizeof(float); - t = *(float *)curPos; - curPos = curPos + sizeof(float); - r = *(float *)curPos; - curPos = curPos + sizeof(float); - TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r); - glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); - break; - - default: - r=0;q=0; /* Avoid compiler warnings, need these vars later for other textures */ - FIXME("Unhandled texture type\n"); - } + switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) { + case D3DRTYPE_TEXTURE: + s = *(float *)curPos; + curPos = curPos + sizeof(float); + t = *(float *)curPos; + curPos = curPos + sizeof(float); + TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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; + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); + } + break; + + case D3DRTYPE_VOLUMETEXTURE: + s = *(float *)curPos; + curPos = curPos + sizeof(float); + t = *(float *)curPos; + curPos = curPos + sizeof(float); + r = *(float *)curPos; + curPos = curPos + sizeof(float); + TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r); + + if (NULL != vertex_shader && NULL != vertex_shader->function) { + 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; + } else { + glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); + } + break; + + default: + r = 0.0f; q = 0.0f; /* Avoid compiler warnings, need these vars later for other textures */ + FIXME("Unhandled texture type\n"); + } } else { - /* Note I have seen a program actually do this, so just hide it and continue */ - TRACE("Very odd - texture requested in FVF but not bound!\n"); + /* Note I have seen a program actually do this, so just hide it and continue */ + TRACE("Very odd - texture requested in FVF but not bound!\n"); } } + /** if vertex shader specified ... using it */ + if (NULL != vertex_shader && NULL != vertex_shader->function) { + vshader_output_data vs_o; + memset(&vs_o, 0, sizeof(vshader_output_data)); + vshader_program_execute_SW(vertex_shader, &vertex_shader_input, &vs_o); + + x = vs_o.oPos.x; + y = vs_o.oPos.y; + z = vs_o.oPos.z; + + if (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]); + } + 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]); + } + + /** TODO: reupdate textures coords binding using vs_o.oT[0->3] */ + for (textureNo = 0; textureNo < min(numTextures, 4); ++textureNo) { + float s, t, r, q; + /* Query tex coords */ + 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; + TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t); + glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t); + 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; + TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r); + glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r); + break; + + default: + /* Avoid compiler warnings, need these vars later for other textures */ + r = 0.0f; q = 0.0f; + FIXME("Unhandled texture type\n"); + } + } + } + } + /* Handle these vertexes */ if (isDiffuse) { glColor4f(((diffuseColor >> 16) & 0xFF) / 255.0, ((diffuseColor >> 8) & 0xFF) / 255.0, ((diffuseColor >> 0) & 0xFF) / 255.0, ((diffuseColor >> 24) & 0xFF) / 255.0); - TRACE("glColor4f: r,g,b,a=%f,%f,%f,%f\n", ((diffuseColor >> 16) & 0xFF) / 255.0, ((diffuseColor >> 8) & 0xFF) / 255.0, - ((diffuseColor >> 0) & 0xFF) / 255.0, ((diffuseColor >> 24) & 0xFF) / 255.0); + TRACE("glColor4f: r,g,b,a=%f,%f,%f,%f\n", + ((diffuseColor >> 16) & 0xFF) / 255.0, + ((diffuseColor >> 8) & 0xFF) / 255.0, + ((diffuseColor >> 0) & 0xFF) / 255.0, + ((diffuseColor >> 24) & 0xFF) / 255.0); } if (normal) { @@ -3152,19 +3292,14 @@ object->decl = pDeclaration; object->function = pFunction; - /* - for (i = 0; 0xFFFFFFFF != pDeclaration[i]; ++i) ; - object->declLength = i + 1; - if (NULL != pFunction) { - for (i = 0; 0xFFFFFFFF != pFunction[i]; ++i) ; - object->functionLength = i + 1; - } else { - object->functionLength = 1; // no Function defined use fixed function vertex processing - } - */ vshader_decl_parse(object); vshader_program_parse(object); + /* copy the function ... because it will certainly be released by application */ + if (NULL != pFunction) { + object->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->functionLength); + memcpy(object->function, pFunction, object->functionLength); + } return D3D_OK; } HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) { @@ -3212,8 +3347,6 @@ VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL; return D3D_OK; } - -#define VERTEX_SHADER(Handle) ((Handle <= VS_HIGHESTFIXEDFXF) ? ((Handle >= sizeof(VertexShaders) / sizeof(VERTEXSHADER8*)) ? NULL : VertexShaders[Handle]) : VertexShaders[Handle - VS_HIGHESTFIXEDFXF]) HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) { ICOM_THIS(IDirect3DDevice8Impl,iface); Index: directx.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/directx.c,v retrieving revision 1.8 diff -u -r1.8 directx.c --- directx.c 18 Dec 2002 05:05:41 -0000 1.8 +++ directx.c 19 Dec 2002 00:28:42 -0000 @@ -584,11 +584,13 @@ LEAVE_GL(); - { + + { /* Print some caps infos */ GLint gl_max_texture_units_arb; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max_texture_units_arb); TRACE("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max_texture_units_arb); } + { /* Set a default viewport */ D3DVIEWPORT8 vp; Index: shader.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/shader.c,v retrieving revision 1.2 diff -u -r1.2 shader.c --- shader.c 18 Dec 2002 05:05:41 -0000 1.2 +++ shader.c 19 Dec 2002 00:28:45 -0000 @@ -63,22 +63,39 @@ */ } shader_opcode; -typedef struct vshader_input_data { - /*SHADER8Vector V[16];//0-15*/ - SHADER8Vector V[16]; -} vshader_input_data; - -typedef struct vshader_output_data { - SHADER8Vector oPos; - /*SHADER8Vector oD[2];//0-1*/ - SHADER8Vector oD[2]; - /*SHADER8Vector oT[4];//0-3*/ - SHADER8Vector oT[4]; - /*SHADER8Scalar oFog;*/ - /*SHADER8Scalar oPts;*/ - SHADER8Vector oFog; - SHADER8Vector oPts; -} vshader_output_data; +/** Vertex Shader Declaration data types tokens */ +static CONST char* VertexShaderDeclDataTypes [] = { + "D3DVSDT_FLOAT1", + "D3DVSDT_FLOAT2", + "D3DVSDT_FLOAT3", + "D3DVSDT_FLOAT4", + "D3DVSDT_D3DCOLOR", + "D3DVSDT_UBYTE4", + "D3DVSDT_SHORT2", + "D3DVSDT_SHORT4", + NULL +}; + +static CONST char* VertexShaderDeclRegister [] = { + "D3DVSDE_POSITION", + "D3DVSDE_BLENDWEIGHT", + "D3DVSDE_BLENDINDICES", + "D3DVSDE_NORMAL", + "D3DVSDE_PSIZE", + "D3DVSDE_DIFFUSE", + "D3DVSDE_SPECULAR", + "D3DVSDE_TEXCOORD0", + "D3DVSDE_TEXCOORD1", + "D3DVSDE_TEXCOORD2", + "D3DVSDE_TEXCOORD3", + "D3DVSDE_TEXCOORD4", + "D3DVSDE_TEXCOORD5", + "D3DVSDE_TEXCOORD6", + "D3DVSDE_TEXCOORD7", + "D3DVSDE_POSITION2", + "D3DVSDE_NORMAL2", + NULL +}; /******************************* * vshader functions software VM @@ -97,6 +114,11 @@ void vshader_dp4(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) { d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z + s0->w * s1->w; + + /* + DPRINTF("executing dp4: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w); + */ } void vshader_dst(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) { @@ -104,6 +126,11 @@ d->y = s0->y * s1->y; d->z = s0->z; d->w = s1->w; + + /* + DPRINTF("executing dst: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w); + */ } void vshader_expp(SHADER8Vector* d, SHADER8Vector* s0) { @@ -112,6 +139,11 @@ d->y = s0->w - tmp_f; d->z = pow(2, s0->w); d->w = 1; + + /* + DPRINTF("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w); + */ } void vshader_lit(SHADER8Vector* d, SHADER8Vector* s0) { @@ -119,6 +151,11 @@ d->y = (0 < s0->x) ? s0->x : 0; d->z = (0 < s0->x && 0 < s0->y) ? pow(s0->y, s0->w) : 0; d->w = 1; + + /* + DPRINTF("executing lit: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w); + */ } void vshader_logp(SHADER8Vector* d, SHADER8Vector* s0) { @@ -151,6 +188,11 @@ d->y = s0->y; d->z = s0->z; d->w = s0->w; + + /* + DPRINTF("executing mov: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w); + */ } void vshader_mul(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) { @@ -158,6 +200,11 @@ d->y = s0->y * s1->y; d->z = s0->z * s1->z; d->w = s0->w * s1->w; + + /* + DPRINTF("executing mul: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n", + s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w); + */ } void vshader_nop(void) { @@ -223,6 +270,7 @@ const shader_opcode* vshader_program_get_opcode(const DWORD code) { DWORD i = 0; + /** TODO: use dichotomic search */ while (NULL != vshader_ins[i].name) { if ((code & D3DSI_OPCODE_MASK) == vshader_ins[i].opcode) { return &vshader_ins[i]; @@ -339,7 +387,7 @@ DPRINTF("\n"); } } - vshader->functionLength = len * sizeof(DWORD); + vshader->functionLength = (len + 1) * sizeof(DWORD); } else { vshader->functionLength = 1; /* no Function defined use fixed function vertex processing */ } @@ -347,7 +395,7 @@ } BOOL vshader_program_execute_HAL(VERTEXSHADER8* vshader, - const vshader_input_data* input, + vshader_input_data* input, vshader_output_data* output) { /** * TODO: use the NV_vertex_program (or 1_1) extension @@ -356,6 +404,8 @@ return TRUE; } +#define TRACE_VECTOR(name) DPRINTF( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w) + BOOL vshader_program_execute_SW(VERTEXSHADER8* vshader, vshader_input_data* input, vshader_output_data* output) { @@ -372,35 +422,52 @@ /** functions parameters */ SHADER8Vector* p[4]; SHADER8Vector* p_send[4]; - DWORD i; + /* vshader_program_parse(vshader); */ + /* + TRACE_VECTOR(vshader->data->C[0]); + TRACE_VECTOR(vshader->data->C[1]); + TRACE_VECTOR(vshader->data->C[2]); + TRACE_VECTOR(vshader->data->C[3]); + TRACE_VECTOR(input->V[D3DVSDE_POSITION]); + TRACE_VECTOR(input->V[D3DVSDE_BLENDWEIGHT]); + TRACE_VECTOR(input->V[D3DVSDE_BLENDINDICES]); + TRACE_VECTOR(input->V[D3DVSDE_NORMAL]); + TRACE_VECTOR(input->V[D3DVSDE_PSIZE]); + TRACE_VECTOR(input->V[D3DVSDE_DIFFUSE]); + TRACE_VECTOR(input->V[D3DVSDE_SPECULAR]); + TRACE_VECTOR(input->V[D3DVSDE_TEXCOORD0]); + TRACE_VECTOR(input->V[D3DVSDE_TEXCOORD1]); + */ + /* the first dword is the version tag */ /* TODO: parse it */ - ++pToken; while (D3DVS_END() != *pToken) { curOpcode = vshader_program_get_opcode(*pToken); ++pToken; if (NULL == curOpcode) { /* unkown current opcode ... */ while (*pToken & 0x80000000) { - DPRINTF("unrecognized opcode: %08lX\n", *pToken); + DPRINTF("unrecognized opcode: pos=%d token=%08lX\n", pToken - vshader->function, *pToken); ++pToken; } /*return FALSE;*/ } else { - if (curOpcode->num_params > 0) { - + if (curOpcode->num_params > 0) { + /*DPRINTF(">> execting opcode: pos=%lu opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken);*/ for (i = 0; i < curOpcode->num_params; ++i) { DWORD reg = pToken[i] & 0x00001FFF; DWORD regtype = ((pToken[i] & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); switch (regtype << D3DSP_REGTYPE_SHIFT) { case D3DSPR_TEMP: + /*DPRINTF("p[%d]=R[%d]\n", i, reg);*/ p[i] = &R[reg]; break; case D3DSPR_INPUT: + /*DPRINTF("p[%d]=V[%s]\n", i, VertexShaderDeclRegister[reg]);*/ p[i] = &input->V[reg]; break; case D3DSPR_CONST: @@ -411,8 +478,11 @@ } break; case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ - if (0 != reg) - ERR("cannot handle address registers != a0"); + if (0 != reg) { + ERR("cannot handle address registers != a0, forcing use of a0\n"); + reg = 0; + } + /*DPRINTF("p[%d]=A[%d]\n", i, reg);*/ p[i] = &A[reg]; break; case D3DSPR_RASTOUT: @@ -429,30 +499,45 @@ } break; case D3DSPR_ATTROUT: + /*DPRINTF("p[%d]=oD[%d]\n", i, reg);*/ p[i] = &output->oD[reg]; break; case D3DSPR_TEXCRDOUT: + /*DPRINTF("p[%d]=oT[%d]\n", i, reg);*/ p[i] = &output->oT[reg]; break; default: break; } - if (i > 1) { /* input reg */ + if (i > 0) { /* input reg */ DWORD swizzle = (pToken[i] & D3DVS_SWIZZLE_MASK) >> D3DVS_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; if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) == swizzle) { + /*DPRINTF("p[%d] not swizzled\n", i);*/ p_send[i] = p[i]; } else { - float* tt = (float*) p[i]; - s[i].x = tt[swizzle_x]; - s[i].y = tt[swizzle_y]; - s[i].z = tt[swizzle_z]; - s[i].w = tt[swizzle_w]; - p_send[i] = &s[i]; + /*DPRINTF("p[%d] swizzled\n", i);*/ + if (swizzle_x == swizzle_y && + swizzle_x == swizzle_z && + swizzle_x == swizzle_w) { + float* tt = (float*) p[i]; + s[i].x = tt[swizzle_x]; + s[i].y = 0.0f; + s[i].z = 0.0f; + s[i].w = 0.0f; + p_send[i] = &s[i]; + } else { + float* tt = (float*) p[i]; + s[i].x = tt[swizzle_x]; + s[i].y = tt[swizzle_y]; + s[i].z = tt[swizzle_z]; + s[i].w = tt[swizzle_w]; + p_send[i] = &s[i]; + } } } else { /* output reg */ if ((pToken[i] & D3DSP_WRITEMASK_ALL) == D3DSP_WRITEMASK_ALL) { @@ -491,7 +576,20 @@ if (pToken[0] & D3DSP_WRITEMASK_2) p[0]->z = d.z; if (pToken[0] & D3DSP_WRITEMASK_3) p[0]->w = d.w; } - + + /* + TRACE_VECTOR(output->oPos); + TRACE_VECTOR(output->oD[0]); + TRACE_VECTOR(output->oD[1]); + TRACE_VECTOR(output->oT[0]); + TRACE_VECTOR(output->oT[1]); + TRACE_VECTOR(R[0]); + TRACE_VECTOR(R[1]); + TRACE_VECTOR(R[2]); + TRACE_VECTOR(R[3]); + TRACE_VECTOR(R[4]); + */ + /* to next opcode token */ pToken += curOpcode->num_params; } @@ -503,41 +601,6 @@ * Vertex Shader Declaration Parser First draft ... */ -/** Vertex Shader Declaration data types tokens */ -static CONST char* VertexShaderDeclDataTypes [] = { - "D3DVSDT_FLOAT1", - "D3DVSDT_FLOAT2", - "D3DVSDT_FLOAT3", - "D3DVSDT_FLOAT4", - "D3DVSDT_D3DCOLOR", - "D3DVSDT_UBYTE4", - "D3DVSDT_SHORT2", - "D3DVSDT_SHORT4", - NULL -}; - -static CONST char* VertexShaderDeclRegister [] = { - "D3DVSDE_POSITION", - "D3DVSDE_BLENDWEIGHT", - "D3DVSDE_BLENDINDICES", - "D3DVSDE_NORMAL", - "D3DVSDE_PSIZE", - "D3DVSDE_DIFFUSE", - "D3DVSDE_SPECULAR", - "D3DVSDE_TEXCOORD0", - "D3DVSDE_TEXCOORD1", - "D3DVSDE_TEXCOORD2", - "D3DVSDE_TEXCOORD3", - "D3DVSDE_TEXCOORD4", - "D3DVSDE_TEXCOORD5", - "D3DVSDE_TEXCOORD6", - "D3DVSDE_TEXCOORD7", - "D3DVSDE_POSITION2", - "D3DVSDE_NORMAL2", - NULL -}; - - /** todo check decl validity */ DWORD vshader_decl_parse_token(const DWORD* pToken) { const DWORD token = *pToken; @@ -622,6 +685,7 @@ DWORD token; DWORD tokenlen; DWORD tokentype; + DWORD tex = D3DFVF_TEX0; while (D3DVSD_END() != *pToken) { token = *pToken; @@ -632,8 +696,17 @@ if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) { DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); + switch (reg) { - case D3DVSDE_POSITION: fvf |= D3DFVF_XYZ; break; + case D3DVSDE_POSITION: + switch (type) { + 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); + } + break; case D3DVSDE_BLENDWEIGHT: switch (type) { case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break; @@ -646,31 +719,40 @@ } break; - case D3DVSDE_BLENDINDICES: fvf |= D3DFVF_LASTBETA_UBYTE4; break; - case D3DVSDE_NORMAL: fvf |= D3DFVF_NORMAL; break; - case D3DVSDE_PSIZE: fvf |= D3DFVF_PSIZE; break; - case D3DVSDE_DIFFUSE: fvf |= D3DFVF_DIFFUSE; break; - case D3DVSDE_SPECULAR: fvf |= D3DFVF_SPECULAR; break; - case D3DVSDE_TEXCOORD0: fvf |= D3DFVF_TEX1; break; - case D3DVSDE_TEXCOORD1: fvf |= D3DFVF_TEX2; break; - case D3DVSDE_TEXCOORD2: fvf |= D3DFVF_TEX3; break; - case D3DVSDE_TEXCOORD3: fvf |= D3DFVF_TEX4; break; - case D3DVSDE_TEXCOORD4: fvf |= D3DFVF_TEX5; break; - case D3DVSDE_TEXCOORD5: fvf |= D3DFVF_TEX6; break; - case D3DVSDE_TEXCOORD6: fvf |= D3DFVF_TEX7; break; - case D3DVSDE_TEXCOORD7: fvf |= D3DFVF_TEX8; break; + case D3DVSDE_BLENDINDICES: fvf |= D3DFVF_LASTBETA_UBYTE4; break; /* TODO: undertand ;( */ + case D3DVSDE_NORMAL: fvf |= D3DFVF_NORMAL; break; /* TODO: only FLOAT3 supported ... another choice possible ? */ + case D3DVSDE_PSIZE: fvf |= D3DFVF_PSIZE; break; /* TODO: only FLOAT1 supported ... another choice possible ? */ + case D3DVSDE_DIFFUSE: fvf |= D3DFVF_DIFFUSE; break; /* TODO: only FLOAT1 supported */ + case D3DVSDE_SPECULAR: fvf |= D3DFVF_SPECULAR; break; /* TODO: only FLOAT1 supported */ + /** + * TODO: for TEX* only FLOAT2 supported + * by default using texture type info + */ + case D3DVSDE_TEXCOORD0: tex = max(tex, D3DFVF_TEX1); break; + case D3DVSDE_TEXCOORD1: tex = max(tex, D3DFVF_TEX2); break; + case D3DVSDE_TEXCOORD2: tex = max(tex, D3DFVF_TEX3); break; + case D3DVSDE_TEXCOORD3: tex = max(tex, D3DFVF_TEX4); break; + case D3DVSDE_TEXCOORD4: tex = max(tex, D3DFVF_TEX5); break; + case D3DVSDE_TEXCOORD5: tex = max(tex, D3DFVF_TEX6); break; + case D3DVSDE_TEXCOORD6: tex = max(tex, D3DFVF_TEX7); break; + case D3DVSDE_TEXCOORD7: tex = max(tex, D3DFVF_TEX8); break; case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */ case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */ FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token); break; } + /*TRACE("VertexShader declaration define %x as current FVF\n", fvf);*/ } len += tokenlen; pToken += tokenlen; } + if (tex > 0) { + /*TRACE("VertexShader declaration define %x as texture level\n", tex);*/ + fvf |= tex; + } /* here D3DVSD_END() */ len += vshader_decl_parse_token(pToken); - if (NULL == vshader->function) vshader->fvf = fvf; + vshader->fvf = fvf; vshader->declLength = len * sizeof(DWORD); return len * sizeof(DWORD); } @@ -684,3 +766,4 @@ FIXME("(void): stub\n"); return 0; } +