Vertex shader output is lit and transformed, so stop GL doing it all again.
Jason
diff -u3 dlls/d3d8/dx77/drawprim.c dlls/d3d8/drawprim.c --- dlls/d3d8/dx77/drawprim.c 2003-09-18 20:18:24.000000000 +0100 +++ dlls/d3d8/drawprim.c 2003-09-18 23:10:19.000000000 +0100 @@ -214,21 +214,21 @@ /* Setup views - Transformed & lit if RHW, else untransformed. Only unlit if Normals are supplied Returns: Whether to restore lighting afterwards */ -BOOL primitiveInitState(LPDIRECT3DDEVICE8 iface, BOOL vtx_transformed, BOOL vtx_lit) { +BOOL primitiveInitState(LPDIRECT3DDEVICE8 iface, BOOL vtx_transformed, BOOL vtx_lit, BOOL useVS) { BOOL isLightingOn = FALSE; ICOM_THIS(IDirect3DDevice8Impl,iface); /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is - set by the appropriate render state */ - if (vtx_lit) { + set by the appropriate render state. Note Vertex Shader output is already lit */ + if (vtx_lit || useVS) { isLightingOn = glIsEnabled(GL_LIGHTING); glDisable(GL_LIGHTING); checkGLcall("glDisable(GL_LIGHTING);"); TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn); } - if (vtx_transformed) { + if (!useVS && vtx_transformed) { /* If the last draw was transformed as well, no need to reapply all the matrixes */ if (!This->last_was_rhw) { @@ -270,7 +270,7 @@ /* Untransformed, so relies on the view and projection matrices */ - if (This->last_was_rhw || !This->modelview_valid) { + if (!useVS && (This->last_was_rhw || !This->modelview_valid)) { /* Only reapply when have to */ This->modelview_valid = TRUE; glMatrixMode(GL_MODELVIEW); @@ -288,7 +288,7 @@ } } - if (This->last_was_rhw || !This->proj_valid) { + if (!useVS && (This->last_was_rhw || !This->proj_valid)) { /* Only reapply when have to */ This->proj_valid = TRUE; glMatrixMode(GL_PROJECTION); @@ -308,6 +308,24 @@ checkGLcall("glLoadMatrixf"); } + /* Vertex Shader output is already transformed, so set up identity matrices */ + /* FIXME: Actually, only true for software emulated ones, so when h/w ones + come along this needs to take into account whether s/w ones were + requested or not */ + if (useVS) { + glMatrixMode(GL_MODELVIEW); + checkGLcall("glMatrixMode"); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + checkGLcall("glMatrixMode"); + glLoadIdentity(); + /* Window Coord 0 is the middle of the first pixel, so translate by half + a pixel (See comment above glTranslate above) */ + glTranslatef(1.0/This->StateBlock->viewport.Width, -1.0/This->StateBlock->viewport.Height, 0); + checkGLcall("glTranslatef (1.0/width, -1.0/height, 0)"); + This->modelview_valid = FALSE; + This->proj_valid = FALSE; + } This->last_was_rhw = FALSE; } return isLightingOn; @@ -601,7 +619,7 @@ /* Position -------------------------------- */ if (isXYZ == TRUE) { - if (1.0f == rhw || rhw < 0.01f) { + if (1.0f == rhw || rhw < 0.00001f) { VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); glVertex3f(x, y, z); } else { @@ -1166,7 +1184,7 @@ /* Position -------------------------------- */ if (sd->u.s.position.lpData != NULL) { - if (1.0f == rhw || rhw < 0.01f) { + if (1.0f == rhw || rhw < 0.0001f) { VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z)); glVertex3f(x, y, z); } else { @@ -1302,7 +1320,7 @@ /* Draw using this information */ draw_vertex(iface, TRUE, x, y, z, rhw, - FALSE, 0.0f, 0.0f, 0.0f, + TRUE, 0.0f, 0.0f, 1.0f, TRUE, (float*) &vertex_shader->output.oD[0], TRUE, (float*) &vertex_shader->output.oD[1], FALSE, ptSize, /* FIXME: Change back when supported */ @@ -1350,7 +1368,7 @@ /** init Constants */ if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) { - TRACE_(d3d_shader)("vertex shader init Constant\n"); + TRACE_(d3d_shader)("vertex shader initializing constants\n"); IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96); } } @@ -1361,7 +1379,8 @@ /* Setup transform matrices and sort out */ isLightingOn = primitiveInitState(iface, fvf & D3DFVF_XYZRHW, - !(fvf & D3DFVF_NORMAL)); + !(fvf & D3DFVF_NORMAL), + useVertexShaderFunction); /* Initialize all values to null */ if (useVertexShaderFunction == FALSE) { @@ -1422,8 +1441,8 @@ idxData, idxSize, minIndex, StartIdx); } - /* If no normals, restore previous lighting state */ - if (!(fvf & D3DFVF_NORMAL)) { + /* If vertex shaders or no normals, restore previous lighting state */ + if (useVertexShaderFunction || !(fvf & D3DFVF_NORMAL)) { if (isLightingOn) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); TRACE("Restored lighting to original state\n"); diff -u3 dlls/d3d8/dx77/vshaderdeclaration.c dlls/d3d8/vshaderdeclaration.c --- dlls/d3d8/dx77/vshaderdeclaration.c 2003-09-18 20:18:28.000000000 +0100 +++ dlls/d3d8/vshaderdeclaration.c 2003-09-07 15:27:06.000000000 +0100 @@ -245,7 +245,7 @@ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break; case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; if (type >= MAX_VSHADER_DECL_TYPES) { TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported and unrecognized type %08lx\n", type); @@ -262,7 +262,7 @@ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break; case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -272,7 +272,7 @@ switch (type) { case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -282,7 +282,7 @@ switch (type) { case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -292,7 +292,7 @@ switch (type) { case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -302,7 +302,7 @@ switch (type) { case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -312,7 +312,7 @@ switch (type) { case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -336,7 +336,7 @@ case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break; case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break; default: - /** errooooorr mismatched use of a register, invalid fvf computing */ + /** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */ invalid_fvf = TRUE; TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexShaderDeclDataTypes[type]); } @@ -345,7 +345,7 @@ 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 ;( */ - TRACE("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token); + FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token); break; } TRACE("VertexShader declaration define %lx as current FVF\n", fvf); @@ -442,6 +442,7 @@ } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) { /** skip datas */ DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT); + TRACE(" skipping %d dwords\n", skipCount); curPos = curPos + skipCount * sizeof(DWORD); ++pToken; @@ -450,6 +451,7 @@ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); ++pToken; + TRACE(" type : %d, reg = %d\n", type, reg); switch (type) { case D3DVSDT_FLOAT1: x = *(float*) curPos;