From 1df8f18e468c5d16c91375154842cc982d9a837b Mon Sep 17 00:00:00 2001 From: Raphael Junqueira Date: Wed, 18 Dec 2002 05:05:41 +0000 Subject: [PATCH] - some fixes in CreateDevice init - vertex shader declaration parser (with output dump) and interpretation (generate the FVF descriptor for program input) - vertex shader program parser (with output dump) - software vertex shader program emulation --- dlls/d3d8/d3d8_private.h | 13 +- dlls/d3d8/device.c | 41 ++- dlls/d3d8/directx.c | 76 +++++- dlls/d3d8/shader.c | 555 +++++++++++++++++++++++++++++++------- dlls/d3d8/texture.c | 2 +- dlls/d3d8/volumetexture.c | 8 +- 6 files changed, 563 insertions(+), 132 deletions(-) diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 1ff3b58148d..2551ac7579f 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -170,8 +170,8 @@ typedef SHADER8Vector SHADER8Constants[SHADER_MAX_CONSTANTS]; typedef struct SHADER8Data { /** Run Time Shader Function Constants */ - /*D3DXBUFFER* constants; */ - SHADER8Constants constants; + /*D3DXBUFFER* constants;*/ + SHADER8Constants C; /** Shader Code as char ... */ CONST DWORD* code; UINT codeLength; @@ -183,6 +183,8 @@ typedef struct VERTEXSHADER8 { /* TODO: Vertex Shader */ DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */ UINT declLength; UINT functionLength; + + DWORD fvf; /* run time datas */ SHADER8Data* data; @@ -905,4 +907,11 @@ extern HRESULT WINAPI IDirect3DVolumeTexture8Impl_LockBox(LPDIRECT3DVOLU extern HRESULT WINAPI IDirect3DVolumeTexture8Impl_UnlockBox(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level); extern HRESULT WINAPI IDirect3DVolumeTexture8Impl_AddDirtyBox(LPDIRECT3DVOLUMETEXTURE8 iface, CONST D3DBOX* pDirtyBox); +/******************* + * private functions + */ +DWORD vshader_decl_parse(VERTEXSHADER8* vshader); +DWORD vshader_program_parse(VERTEXSHADER8* vshader); + + #endif /* __WINE_D3DX8_PRIVATE_H */ diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 1017aa4174c..7ad03ccc255 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -177,7 +177,7 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface, } else { glMatrixMode(GL_PROJECTION); - checkGLcall("glMatrixMode"); + checkGLcall("glMatrixMode"); glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]); checkGLcall("glLoadMatrixf"); @@ -2153,6 +2153,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3 case D3DRS_INDEXEDVERTEXBLENDENABLE : case D3DRS_COLORWRITEENABLE : case D3DRS_TWEENFACTOR : + case D3DRS_POSITIONORDER : + case D3DRS_NORMALORDER : /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */ TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value); break; @@ -3128,7 +3130,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface VERTEXSHADER8* object; UINT i; - FIXME("(%p) : VertexShader not fully supported yet\n", This); + FIXME("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p\n", This, pDeclaration, pFunction); if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */ return D3DERR_INVALIDCALL; } @@ -3142,21 +3144,26 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface } object->usage = Usage; - object->data = NULL; /* TODO */ + object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADER8Data)); VertexShaders[i] = object; *pHandle = VS_HIGHESTFIXEDFXF + i; object->decl = pDeclaration; + object->function = pFunction; + + /* for (i = 0; 0xFFFFFFFF != pDeclaration[i]; ++i) ; object->declLength = i + 1; - object->function = pFunction; 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 */ + object->functionLength = 1; // no Function defined use fixed function vertex processing } + */ + vshader_decl_parse(object); + vshader_program_parse(object); return D3D_OK; } @@ -3172,7 +3179,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, D TRACE("Recording... not performing anything\n"); return D3D_OK; } - if (Handle <= VS_HIGHESTFIXEDFXF) { TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle); return D3D_OK; @@ -3196,10 +3202,14 @@ HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface return D3DERR_INVALIDCALL; } object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF]; + if (NULL == object) { + return D3DERR_INVALIDCALL; + } TRACE("(%p) : freing VertexShader %p\n", This, object); /* TODO: check validity of object */ + if (NULL != object->data) HeapFree(GetProcessHeap(), 0, (void *)object->data); HeapFree(GetProcessHeap(), 0, (void *)object); - VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = 0; + VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL; return D3D_OK; } @@ -3210,8 +3220,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 VERTEXSHADER8* object; DWORD Handle = This->UpdateStateBlock->VertexShader; - FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); - + /* FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); */ if (Register + ConstantCount > VSHADER_MAX_CONSTANTS) { return D3DERR_INVALIDCALL; } @@ -3219,7 +3228,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 if (NULL == object || NULL == pConstantData) { return D3DERR_INVALIDCALL; } - memcpy(object->data->constants + Register, pConstantData, ConstantCount * sizeof(SHADER8Vector)); + if (NULL == object->data) { /* temporary while datas not supported */ + FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This); + return D3DERR_INVALIDCALL; + } + memcpy(object->data->C + Register, pConstantData, ConstantCount * sizeof(SHADER8Vector)); return D3D_OK; } @@ -3237,7 +3250,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 if (NULL == object || NULL == pConstantData) { return D3DERR_INVALIDCALL; } - memcpy(pConstantData, object->data->constants + Register, ConstantCount * sizeof(SHADER8Vector)); + if (NULL == object->data) { /* temporary while datas not supported */ + return D3DERR_INVALIDCALL; + } + memcpy(pConstantData, object->data->C + Register, ConstantCount * sizeof(SHADER8Vector)); return D3D_OK; } @@ -3288,10 +3304,9 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 } HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) { - + ICOM_THIS(IDirect3DDevice8Impl,iface); IDirect3DIndexBuffer8 *oldIdxs; - ICOM_THIS(IDirect3DDevice8Impl,iface); TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex); oldIdxs = This->StateBlock.pIndexData; diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index f59523ab93c..2018b328f62 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -382,7 +382,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, IDirect3DDevice8** ppReturnedDeviceInterface) { IDirect3DDevice8Impl *object; HWND whichHWND; + int num; + XVisualInfo template; const char *GL_Extensions = NULL; + const char *GLX_Extensions = NULL; ICOM_THIS(IDirect3D8Impl,iface); TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This, Adapter, DeviceType, @@ -390,6 +393,9 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, /* Allocate the storage for the device */ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl)); + if (NULL == object) { + return D3DERR_OUTOFVIDEOMEMORY; + } object->lpVtbl = &Direct3DDevice8_Vtbl; object->ref = 1; object->direct3d8 = This; @@ -417,6 +423,7 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, HDC hDc; int dblBuf[]={GLX_STENCIL_SIZE,8,GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None}; /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */ + /*int dblBuf[]={GLX_RGBA,GLX_RED_SIZE,4,GLX_GREEN_SIZE,4,GLX_BLUE_SIZE,4,GLX_DOUBLEBUFFER,None}; */ /* Which hwnd are we using? */ /* if (pPresentationParameters->Windowed) { */ @@ -437,12 +444,32 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, object->display = get_display(hDc); ENTER_GL(); - object->visInfo = glXChooseVisual(object->display, DefaultScreen(object->display), dblBuf); - object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE); + object->visInfo = glXChooseVisual(object->display, DefaultScreen(object->display), dblBuf); + if (NULL == object->visInfo) { + FIXME("cannot choose needed glxVisual with Stencil Buffer\n"); + /** + * second try using wine initialized visual ... + * must be fixed reworking wine-glx init + */ + template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" ); + object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num); + if (NULL == object->visInfo) { + ERR("cannot really get XVisual\n"); + LEAVE_GL(); + return D3DERR_NOTAVAILABLE; + } + } + + object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE); + if (NULL == object->visInfo) { + ERR("cannot create glxContext\n"); + LEAVE_GL(); + return D3DERR_NOTAVAILABLE; + } LEAVE_GL(); - ReleaseDC(whichHWND, hDc); + ReleaseDC(whichHWND, hDc); } if (object->glCtx == NULL) { @@ -492,8 +519,7 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, ENTER_GL(); if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) { - ERR("Error in setting current context (context %p drawable %ld)!\n", - object->glCtx, object->win); + ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win); } checkGLcall("glXMakeCurrent"); @@ -509,7 +535,7 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);"); - glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); checkGLcall("glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);"); /* Setup all the devices defaults */ @@ -518,22 +544,52 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface, /* Parse the gl supported features, in theory enabling parts of our code appropriately */ GL_Extensions = glGetString(GL_EXTENSIONS); TRACE("GL_Extensions reported:\n"); - - while (*GL_Extensions!=0x00) { + + if (NULL == GL_Extensions) { + ERR(" GL_Extensions returns NULL\n"); + } else { + while (*GL_Extensions!=0x00) { const char *Start = GL_Extensions; char ThisExtn[256]; - + memset(ThisExtn, 0x00, sizeof(ThisExtn)); while (*GL_Extensions!=' ' && *GL_Extensions!=0x00) { - GL_Extensions++; + GL_Extensions++; } memcpy(ThisExtn, Start, (GL_Extensions-Start)); TRACE (" %s\n", ThisExtn); if (*GL_Extensions==' ') GL_Extensions++; + } + } + + GLX_Extensions = glXQueryExtensionsString(object->display, DefaultScreen(object->display)); + TRACE("GLX_Extensions reported:\n"); + + if (NULL == GLX_Extensions) { + ERR(" GLX_Extensions returns NULL\n"); + } else { + while (*GLX_Extensions!=0x00) { + const char *Start = GLX_Extensions; + char ThisExtn[256]; + + memset(ThisExtn, 0x00, sizeof(ThisExtn)); + while (*GLX_Extensions!=' ' && *GLX_Extensions!=0x00) { + GLX_Extensions++; + } + memcpy(ThisExtn, Start, (GLX_Extensions-Start)); + TRACE (" %s\n", ThisExtn); + if (*GLX_Extensions==' ') GLX_Extensions++; + } } LEAVE_GL(); + { + 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; vp.X = 0; diff --git a/dlls/d3d8/shader.c b/dlls/d3d8/shader.c index 206eada5b12..bde09abfed5 100644 --- a/dlls/d3d8/shader.c +++ b/dlls/d3d8/shader.c @@ -64,41 +64,24 @@ typedef struct shader_opcode { } shader_opcode; typedef struct vshader_input_data { - /*SHADER8Vector V[16];//0-15 */ - SHADER8Vector V0; - SHADER8Vector V1; - SHADER8Vector V2; - SHADER8Vector V3; - SHADER8Vector V4; - SHADER8Vector V5; - SHADER8Vector V6; - SHADER8Vector V7; - SHADER8Vector V8; - SHADER8Vector V9; - SHADER8Vector V10; - SHADER8Vector V11; - SHADER8Vector V12; - SHADER8Vector V13; - SHADER8Vector V14; - SHADER8Vector V15; + /*SHADER8Vector V[16];//0-15*/ + SHADER8Vector V[16]; } vshader_input_data; typedef struct vshader_output_data { SHADER8Vector oPos; - /*SHADER8Vector oD[2];//0-1 */ - SHADER8Vector oD0; - SHADER8Vector oD1; - /*SHADER8Vector oT[4];//0-3 */ - SHADER8Vector oT0; - SHADER8Vector oT1; - SHADER8Vector oT2; - SHADER8Vector oT3; - SHADER8Scalar oFog; - SHADER8Scalar oPts; + /*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; -/********************* - * vshader software VM +/******************************* + * vshader functions software VM */ void vshader_add(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) { @@ -215,123 +198,489 @@ void vshader_sub(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) { * * @TODO: find this fucking really opcodes values */ -static CONST shader_opcode vshader_ins [] = - { - {0, "mov", 2, vshader_mov}, - {0, "max", 3, vshader_max}, - {0, "min", 3, vshader_min}, - {0, "sge", 3, vshader_sge}, - {0, "slt", 3, vshader_slt}, - {0, "add", 3, vshader_add}, - {0, "sub", 3, vshader_sub}, - {0, "mul", 3, vshader_mul}, - {0, "rcp", 2, vshader_rcp}, - {0, "mad", 4, vshader_mad}, - {0, "dp3", 3, vshader_dp3}, - {0, "dp4", 3, vshader_dp4}, - {0, "rsq", 2, vshader_rsq}, - {0, "dst", 3, vshader_dst}, - {0, "lit", 2, vshader_lit}, - {0, "expp", 2, vshader_expp}, - {0, "logp", 2, vshader_logp}, - {0, "nop", 0, vshader_nop}, - {0, NULL, 0, NULL} - }; +static CONST shader_opcode vshader_ins [] = { + {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_MUL, "mul", 3, vshader_mul}, + {D3DSIO_RCP, "rcp", 2, vshader_rcp}, + {D3DSIO_MAD, "mad", 4, vshader_mad}, + {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_LIT, "lit", 2, vshader_lit}, + {D3DSIO_EXPP, "expp", 2, vshader_expp}, + {D3DSIO_LOGP, "logp", 2, vshader_logp}, + {D3DSIO_NOP, "nop", 0, vshader_nop}, + {0, NULL, 0, NULL} +}; -shader_opcode* vshader_get_opcode(const DWORD code) { +const shader_opcode* vshader_program_get_opcode(const DWORD code) { + DWORD i = 0; + while (NULL != vshader_ins[i].name) { + if ((code & D3DSI_OPCODE_MASK) == vshader_ins[i].opcode) { + return &vshader_ins[i]; + } + ++i; + } return NULL; } +void vshader_program_dump_param(const DWORD param, int input) { + static const char* rastout_reg_names[] = { "oPos", "oFog", "oPts" }; + static const char swizzle_reg_chars[] = "xyzw"; + + DWORD reg = param & 0x00001FFF; + DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); + + if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) DPRINTF("-"); + + switch (regtype << D3DSP_REGTYPE_SHIFT) { + case D3DSPR_TEMP: + DPRINTF("R[%lu]", reg); + break; + case D3DSPR_INPUT: + DPRINTF("V[%lu]", reg); + break; + case D3DSPR_CONST: + DPRINTF("C[%s%lu]", (reg & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg); + break; + case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ + DPRINTF("a[%lu]", reg); + break; + case D3DSPR_RASTOUT: + DPRINTF("%s", rastout_reg_names[reg]); + break; + case D3DSPR_ATTROUT: + DPRINTF("oD[%lu]", reg); + break; + case D3DSPR_TEXCRDOUT: + DPRINTF("oT[%lu]", reg); + break; + default: + break; + } + + if (!input) { + /** operand output */ + if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { + if (param & D3DSP_WRITEMASK_0) DPRINTF(".x"); + if (param & D3DSP_WRITEMASK_1) DPRINTF(".y"); + if (param & D3DSP_WRITEMASK_2) DPRINTF(".z"); + if (param & D3DSP_WRITEMASK_3) DPRINTF(".w"); + } + } else { + /** operand input */ + DWORD swizzle = (param & 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; + /** + * swizzle bits fields: + * WWZZYYXX + */ + if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */ + if (swizzle_x == swizzle_y && + swizzle_x == swizzle_z && + swizzle_x == swizzle_w) { + DPRINTF(".%c", swizzle_reg_chars[swizzle_x]); + } else { + DPRINTF(".%c%c%c%c", + swizzle_reg_chars[swizzle_x], + swizzle_reg_chars[swizzle_y], + swizzle_reg_chars[swizzle_z], + swizzle_reg_chars[swizzle_w]); + } + } + } +} + /** * Function parser ... */ -BOOL vshader_parse_function(const DWORD* function) { - return TRUE; +DWORD vshader_program_parse(VERTEXSHADER8* vshader) { + const DWORD* pToken = vshader->function; + const shader_opcode* curOpcode = NULL; + DWORD len = 0; + DWORD i; + + if (NULL != pToken) { + while (D3DVS_END() != *pToken) { + curOpcode = vshader_program_get_opcode(*pToken); + ++pToken; + ++len; + if (NULL == curOpcode) { + /* unkown current opcode ... */ + while (*pToken & 0x80000000) { + DPRINTF("unrecognized opcode: %08lX\n", *pToken); + ++pToken; + ++len; + } + } else { + DPRINTF("%s ", curOpcode->name); + if (curOpcode->num_params > 0) { + vshader_program_dump_param(*pToken, 0); + ++pToken; + ++len; + for (i = 1; i < curOpcode->num_params; ++i) { + DPRINTF(", "); + vshader_program_dump_param(*pToken, 1); + ++pToken; + ++len; + } + } + DPRINTF("\n"); + } + } + vshader->functionLength = len * sizeof(DWORD); + } else { + vshader->functionLength = 1; /* no Function defined use fixed function vertex processing */ + } + return len * sizeof(DWORD); } -BOOL vshader_hardware_execute_function(VERTEXSHADER8* vshader, - const vshader_input_data* input, - vshader_output_data* output) { +BOOL vshader_program_execute_HAL(VERTEXSHADER8* vshader, + const vshader_input_data* input, + vshader_output_data* output) { /** - * TODO: use the GL_NV_vertex_program - * and specifics vendors variants for it + * TODO: use the NV_vertex_program (or 1_1) extension + * and specifics vendors (ARB_vertex_program??) variants for it */ return TRUE; } -BOOL vshader_software_execute_function(VERTEXSHADER8* vshader, - const vshader_input_data* input, - vshader_output_data* output) { +BOOL vshader_program_execute_SW(VERTEXSHADER8* vshader, + vshader_input_data* input, + vshader_output_data* output) { /** Vertex Shader Temporary Registers */ - /*SHADER8Vector R[12];*/ + SHADER8Vector R[12]; /*SHADER8Scalar A0;*/ + SHADER8Vector A[1]; /** temporary Vector for modifier management */ - /*SHADER8Vector d;*/ + SHADER8Vector d; + SHADER8Vector s[3]; /** parser datas */ const DWORD* pToken = vshader->function; - shader_opcode* curOpcode = NULL; - + const shader_opcode* curOpcode = NULL; + /** functions parameters */ + SHADER8Vector* p[4]; + SHADER8Vector* p_send[4]; + + DWORD i; + /* the first dword is the version tag */ /* TODO: parse it */ ++pToken; - while (0xFFFFFFFF != *pToken) { - curOpcode = vshader_get_opcode(*pToken); + while (D3DVS_END() != *pToken) { + curOpcode = vshader_program_get_opcode(*pToken); ++pToken; if (NULL == curOpcode) { /* unkown current opcode ... */ - return FALSE; - } - if (curOpcode->num_params > 0) { - /* TODO */ + while (*pToken & 0x80000000) { + DPRINTF("unrecognized opcode: %08lX\n", *pToken); + ++pToken; + } + /*return FALSE;*/ + } else { + if (curOpcode->num_params > 0) { + + 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: + p[i] = &R[reg]; + break; + case D3DSPR_INPUT: + p[i] = &input->V[reg]; + break; + case D3DSPR_CONST: + if (reg & D3DVS_ADDRMODE_RELATIVE) { + p[i] = &vshader->data->C[(DWORD) A[0].x + reg]; + } else { + p[i] = &vshader->data->C[reg]; + } + break; + case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ + if (0 != reg) + ERR("cannot handle address registers != a0"); + p[i] = &A[reg]; + break; + case D3DSPR_RASTOUT: + switch (reg) { + case D3DSRO_POSITION: + p[i] = &output->oPos; + break; + case D3DSRO_FOG: + p[i] = &output->oFog; + break; + case D3DSRO_POINT_SIZE: + p[i] = &output->oPts; + break; + } + break; + case D3DSPR_ATTROUT: + p[i] = &output->oD[reg]; + break; + case D3DSPR_TEXCRDOUT: + p[i] = &output->oT[reg]; + break; + default: + break; + } + + if (i > 1) { /* 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) { + 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]; + } + } else { /* output reg */ + if ((pToken[i] & D3DSP_WRITEMASK_ALL) == D3DSP_WRITEMASK_ALL) { + p_send[i] = p[i]; + } else { + p_send[i] = &d; /* to be post-processed for modifiers management */ + } + } + } + } + + switch (curOpcode->num_params) { + case 0: + curOpcode->soft_fct(); + break; + case 1: + curOpcode->soft_fct(p_send[0]); + break; + case 2: + curOpcode->soft_fct(p_send[0], p_send[1]); + break; + case 3: + curOpcode->soft_fct(p_send[0], p_send[1], p_send[2]); + break; + case 4: + curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3]); + break; + default: + ERR("%s too many params: %u\n", curOpcode->name, curOpcode->num_params); + } + + /* check if output reg modifier post-process */ + if (curOpcode->num_params > 0 && (pToken[0] & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) { + if (pToken[0] & D3DSP_WRITEMASK_0) p[0]->x = d.x; + if (pToken[0] & D3DSP_WRITEMASK_1) p[0]->y = d.y; + if (pToken[0] & D3DSP_WRITEMASK_2) p[0]->z = d.z; + if (pToken[0] & D3DSP_WRITEMASK_3) p[0]->w = d.w; + } + + /* to next opcode token */ + pToken += curOpcode->num_params; } } return TRUE; } -/** - * Declaration Parser First draft ... +/************************************ + * Vertex Shader Declaration Parser First draft ... */ -#if 0 -static CONST char* vshader_decl [] = - { - "D3DVSDT_D3DCOLOR", - "D3DVSDT_FLOAT1", - "D3DVSDT_FLOAT2", - "D3DVSDT_FLOAT3", - "D3DVSDT_FLOAT4", - "D3DVSDT_UBYTE4", - NULL - }; -#endif - -/** Vertex Shader Declaration parser tokens */ -enum D3DVSD_TOKENS { - D3DVSD_STREAM, - - D3DVSD_END +/** 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 }; -BOOL vshader_parse_declaration(VERTEXSHADER8* vshader) { - /** parser data */ - const DWORD* pToken = vshader->decl; +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 +}; - ++pToken; - while (0xFFFFFFFF != *pToken) { - /** TODO */ - ++pToken; + +/** todo check decl validity */ +DWORD vshader_decl_parse_token(const DWORD* pToken) { + const DWORD token = *pToken; + DWORD tokenlen = 1; + + switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */ + case D3DVSD_TOKEN_NOP: + TRACE(" 0x%08lx NOP()\n", token); + break; + case D3DVSD_TOKEN_STREAM: + if (token & D3DVSD_STREAMTESSMASK) { + TRACE(" 0x%08lx STREAM_TESS()\n", token); + } else { + TRACE(" 0x%08lx STREAM(%lu)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT)); + } + break; + case D3DVSD_TOKEN_STREAMDATA: + if (token & 0x10000000) { + TRACE(" 0x%08lx SKIP(%lu)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT)); + } else { + DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); + DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); + TRACE(" 0x%08lx REG(%s, %s)\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); + } + break; + case D3DVSD_TOKEN_TESSELLATOR: + if (token & 0x10000000) { + DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); + DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); + TRACE(" 0x%08lx TESSUV(%s) as %s\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]); + } else { + DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT); + DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT); + DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT); + TRACE(" 0x%08lx TESSNORMAL(%s, %s) as %s\n", token, VertexShaderDeclRegister[regin], VertexShaderDeclRegister[regout], VertexShaderDeclDataTypes[type]); + } + break; + case D3DVSD_TOKEN_CONSTMEM: + { + DWORD i; + DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); + DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT); + TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count); + ++pToken; + for (i = 0; i < count; ++i) { + TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n", + constaddress, + *pToken, + *(pToken + 1), + *(pToken + 2), + *(pToken + 3)); + pToken += 4; + ++constaddress; + } + tokenlen = count + 1; + } + break; + case D3DVSD_TOKEN_EXT: + { + DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT); + DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT); + TRACE(" 0x%08lx EXT(%lu, %lu)\n", token, count, extinfo); + /* todo ... print extension */ + tokenlen = count + 1; + } + break; + case D3DVSD_TOKEN_END: + TRACE(" 0x%08lx END()\n", token); + break; + default: + TRACE(" 0x%08lx UNKNOWN\n", token); + /* argg error */ } - return TRUE; + return tokenlen; } -HRESULT WINAPI ValidatePixelShader(void) { - FIXME("(void): stub\n"); - return 0; +DWORD vshader_decl_parse(VERTEXSHADER8* vshader) { + /** parser data */ + const DWORD* pToken = vshader->decl; + DWORD fvf = 0; + DWORD len = 0; + DWORD token; + DWORD tokenlen; + DWORD tokentype; + + while (D3DVSD_END() != *pToken) { + token = *pToken; + tokenlen = vshader_decl_parse_token(pToken); + tokentype = ((*pToken & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT); + + /** FVF generation block */ + 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_BLENDWEIGHT: + switch (type) { + case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break; + case D3DVSDT_FLOAT2: fvf |= D3DFVF_XYZB2; break; + 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); + } + 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_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; + } + } + len += tokenlen; + pToken += tokenlen; + } + /* here D3DVSD_END() */ + len += vshader_decl_parse_token(pToken); + if (NULL == vshader->function) vshader->fvf = fvf; + vshader->declLength = len * sizeof(DWORD); + return len * sizeof(DWORD); } HRESULT WINAPI ValidateVertexShader(void) { FIXME("(void): stub\n"); return 0; } + +HRESULT WINAPI ValidatePixelShader(void) { + FIXME("(void): stub\n"); + return 0; +} diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index de99c2dd54c..85619268f2b 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -107,7 +107,7 @@ D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) { return This->ResourceType; } -/* IDirect3DTexture8 (Inherited from IDirect3DBaseTexture8) */ +/* IDirect3DTexture8 IDirect3DBaseTexture8 Interface follow: */ DWORD WINAPI IDirect3DTexture8Impl_SetLOD(LPDIRECT3DTEXTURE8 iface, DWORD LODNew) { ICOM_THIS(IDirect3DTexture8Impl,iface); FIXME("(%p) : stub\n", This); return D3D_OK; diff --git a/dlls/d3d8/volumetexture.c b/dlls/d3d8/volumetexture.c index 9f4f2e2d4b4..d283381075f 100644 --- a/dlls/d3d8/volumetexture.c +++ b/dlls/d3d8/volumetexture.c @@ -36,7 +36,9 @@ HRESULT WINAPI IDirect3DVolumeTexture8Impl_QueryInterface(LPDIRECT3DVOLUMETEXTUR TRACE("(%p) : QueryInterface\n", This); if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IClassFactory)) { + || IsEqualGUID(riid, &IID_IDirect3DResource8) + || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) + || IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8)) { IDirect3DVolumeTexture8Impl_AddRef(iface); *ppobj = This; return D3D_OK; @@ -55,7 +57,7 @@ ULONG WINAPI IDirect3DVolumeTexture8Impl_AddRef(LPDIRECT3DVOLUMETEXTURE8 iface) ULONG WINAPI IDirect3DVolumeTexture8Impl_Release(LPDIRECT3DVOLUMETEXTURE8 iface) { ICOM_THIS(IDirect3DVolumeTexture8Impl,iface); ULONG ref = --This->ref; - int i; + UINT i; TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref); if (ref == 0) { @@ -107,7 +109,7 @@ D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTU return This->ResourceType; } -/* IDirect3DVolumeTexture8 (Inherited from IDirect3DBaseTexture8) */ +/* IDirect3DVolumeTexture8 IDirect3DBaseTexture8 Interface follow: */ DWORD WINAPI IDirect3DVolumeTexture8Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE8 iface, DWORD LODNew) { ICOM_THIS(IDirect3DVolumeTexture8Impl,iface); FIXME("(%p) : stub\n", This); return D3D_OK;