-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, the new year version of vertex shader ;) Changelog: - little IDirect3DRessource8 COM fix - fix for correctly using diffuse color - change for future specular color management - many new VS1.1/2.0 opcodes (in my doc it's only 2.0 opcodes but many samples need it): m*x* and frc - fixes in opcodes code - more human readable traces - first draft of multi-stream vertex shader (as used in DolphinVS dx8 sdk) (who have a doc ?) - indents Problems: - i can't get my glx init always working ;((( - textures problems (simple samples works) TODO: - more and more d3dx8 (interfaces, compilation, mesh loading, ...) - finish vs2.0 and begin vs3.0 support (who wants to code a HLSL compliator ?) - merge hardware execution code prototype with the software code - finish the D3DASM -> NVASM converter (before i have to find a GeForce card) - try to do a D3DASM -> ATIASM converter Happy new year, Raphael PS: alexandre do you want i resend the d3dx8 patches or its ok ? (my version is really broken because of d3d9 tests) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQE+Fjv1p7NA3AmQTU4RAkYZAJ90zrIp0yorGOdSWjRC0C61GTFTMwCdGosB ciQ49uQ67w6OmA4036OI1oE= =dhyy -----END PGP SIGNATURE-----
Index: shader.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/shader.c,v retrieving revision 1.4 diff -u -r1.4 shader.c --- shader.c 2 Jan 2003 19:28:09 -0000 1.4 +++ shader.c 4 Jan 2003 01:16:53 -0000 @@ -26,6 +26,6 @@ #include <math.h> #include "d3d8_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); @@ -137,10 +140,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 +252,125 @@ } /** + * 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_LIT, "lit", 2, vshader_lit}, + {D3DSIO_DST, "dst", 3, vshader_dst}, {D3DSIO_EXPP, "expp", 2, vshader_expp}, {D3DSIO_LOGP, "logp", 2, vshader_logp}, - {D3DSIO_NOP, "nop", 0, vshader_nop}, + + /** new VS1.1 not fully supported yet */ + {D3DSIO_EXP, "exp", 2, vshader_exp}, + {D3DSIO_LOG, "log", 2, vshader_log}, + {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}, + /** new VS2.0 not fully supported yet */ + {D3DSIO_LRP, "lrp", 5, vshader_lrp}, + {0, NULL, 0, NULL} }; @@ -413,6 +518,7 @@ VSHADEROUTPUTDATA8* output) { /** Vertex Shader Temporary Registers */ D3DSHADERVECTOR R[12]; + memset(R, 0, 12 * sizeof(D3DSHADERVECTOR)); /*D3DSHADERSCALAR A0;*/ D3DSHADERVECTOR A[1]; /** temporary Vector for modifier management */ @@ -426,7 +532,6 @@ D3DSHADERVECTOR* p_send[4]; DWORD i; - memset(R, 0, 12 * sizeof(D3DSHADERVECTOR)); /* vshader_program_parse(vshader); */ /* TRACE_VECTOR(vshader->data->C[0]); @@ -453,9 +558,19 @@ curOpcode = vshader_program_get_opcode(*pToken); ++pToken; if (NULL == curOpcode) { + if (*(pToken - 1) == D3DVS_VERSION(1,1)) { + continue ; + } + 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 +676,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 +796,7 @@ const DWORD* pToken = vshader->decl; DWORD fvf = 0; DWORD len = 0; + DWORD stream = 0; DWORD token; DWORD tokenlen; DWORD tokentype; @@ -686,12 +805,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 +825,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 +836,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 +844,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 +852,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 +860,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 +868,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 +876,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; @@ -802,3 +928,4 @@ FIXME("(void): stub: %p\n", what); return TRUE; } + Index: resource.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/resource.c,v retrieving revision 1.1 diff -u -r1.1 resource.c --- resource.c 27 Sep 2002 22:46:17 -0000 1.1 +++ resource.c 4 Jan 2003 01:16:54 -0000 @@ -34,7 +34,7 @@ ICOM_THIS(IDirect3DResource8Impl,iface); if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IClassFactory)) { + || IsEqualGUID(riid, &IID_IDirect3DResource8)) { IDirect3DResource8Impl_AddRef(iface); *ppobj = This; return D3D_OK; Index: device.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/device.c,v retrieving revision 1.20 diff -u -r1.20 device.c --- device.c 3 Jan 2003 21:28:05 -0000 1.20 +++ device.c 4 Jan 2003 01:17:04 -0000 @@ -265,7 +268,7 @@ vertex arrays, we need to drop down to the slow mechanism for certain functions */ - if (isPtSize || isDiffuse || useVertexShaderFunction==TRUE || (numBlends > 0)) { + if (isPtSize || isDiffuse || useVertexShaderFunction || (numBlends > 0)) { TRACE("Using slow per-vertex code\n"); /* Enable this one to be able to debug what is going on, but it is slower @@ -498,19 +501,22 @@ 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"); + glColor4fv((float*) &vs_o.oD[0]); } +/* Requires secondary color extensions to compile... */ +#if 0 if (isSpecular) { + /* FIXME: check for GL_EXT_secondary_color => Waiting for news CAPS Arch */ /*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"); + glSecondaryColor3fvEXT((float*) &vs_o.oD[1]); + checkGLcall("glSecondaryColor3fvEXT"); } +#endif + /** reupdate textures coords binding using vs_o.oT[0->3] */ - for (textureNo = 0; textureNo < 4/*min(numTextures, 4)*/; ++textureNo) { + for (textureNo = 0; textureNo < 4; ++textureNo) { float s, t, r, q; if (!(This->isMultiTexture) && textureNo > 0) { @@ -565,6 +571,7 @@ glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw); checkGLcall("glVertex4f"); } + } else { /** * FALSE == useVertexShaderFunction @@ -619,16 +626,16 @@ if (isRHW) { glVertexPointer(4, GL_FLOAT, skip, curPos); checkGLcall("glVertexPointer(4, ...)"); - curPos += 4*sizeof(float); + curPos += 4 * sizeof(float); } else { glVertexPointer(3, GL_FLOAT, skip, curPos); checkGLcall("glVertexPointer(3, ...)"); - curPos += 3*sizeof(float); + curPos += 3 * sizeof(float); } glEnableClientState(GL_VERTEX_ARRAY); checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); - if (numBlends>0) { + if (numBlends > 0) { /* no such functionality in the fixed function GL pipeline */ /* FIXME: Wont get here as will drop to slow method */ FIXME("Cannot handle blending data here in openGl\n"); @@ -640,11 +647,11 @@ checkGLcall("glNormalPointer"); glEnableClientState(GL_NORMAL_ARRAY); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); - curPos += 3*sizeof(float); + curPos += 3 * sizeof(float); } else { glDisableClientState(GL_NORMAL_ARRAY); checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)"); - glNormal3f(0, 0, 1); + glNormal3f(0.0f, 0.0f, 1.0f); checkGLcall("glNormal3f(0, 0, 1)"); } @@ -665,7 +672,7 @@ else { glDisableClientState(GL_COLOR_ARRAY); checkGLcall("glDisableClientState(GL_COLOR_ARRAY)"); - glColor4f(1, 1, 1, 1); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); checkGLcall("glColor4f(1, 1, 1, 1)"); } @@ -681,7 +688,7 @@ } else { glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - glSecondaryColor3fEXT(0, 0, 0); + glSecondaryColor3fEXT(0.0f, 0.0f, 0.0f); checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); } #endif @@ -697,7 +704,7 @@ case D3DRTYPE_TEXTURE: glTexCoordPointer(2, GL_FLOAT, skip, curPos); checkGLcall("glTexCoordPointer(2, ...)"); - curPos += 2*sizeof(float); + curPos += 2 * sizeof(float); glEnableClientState(GL_TEXTURE_COORD_ARRAY); checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);"); break; @@ -705,7 +712,7 @@ case D3DRTYPE_VOLUMETEXTURE: glTexCoordPointer(3, GL_FLOAT, skip, curPos); checkGLcall("glTexCoordPointer(3, ...)"); - curPos += 3*sizeof(float); + curPos += 3 * sizeof(float); glEnableClientState(GL_TEXTURE_COORD_ARRAY); checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);"); break; @@ -720,7 +727,7 @@ /* 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"); - glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1); + glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0.0f, 0.0f, 0.0f, 1.0f); checkGLcall("glMultiTexCoord4f(... , 0, 0, 0, 1)"); glDisableClientState(GL_TEXTURE_COORD_ARRAY); checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);"); @@ -728,7 +735,6 @@ } } - /* Finally do the drawing */ if (isIndexed) {