diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index e3c21e33fdb..e984b9da65d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -621,8 +621,10 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { char reg_dest[40]; char reg_coord[40]; + const char *tex_type; DWORD reg_dest_code; DWORD reg_sampler_code; + DWORD sampler_type; /* All versions have a destination register */ reg_dest_code = dst & D3DSP_REGNUM_MASK; @@ -642,12 +644,35 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { else reg_sampler_code = src[1] & D3DSP_REGNUM_MASK; + sampler_type = arg->reg_maps->samplers[reg_sampler_code] & WINED3DSP_TEXTURETYPE_MASK; + switch(sampler_type) { + case WINED3DSTT_1D: + tex_type = "1D"; + break; + + case WINED3DSTT_2D: + tex_type = "2D"; + break; + + case WINED3DSTT_VOLUME: + tex_type = "3D"; + break; + + case WINED3DSTT_CUBE: + tex_type = "CUBE"; + break; + + default: + ERR("Unexpected texture type %ld\n", sampler_type); + tex_type = "2D"; + } + if(This->wineD3DDevice->stateBlock->textureState[reg_sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) { - shader_addline(buffer, "TXP %s, %s, texture[%lu], 2D;\n", - reg_dest, reg_coord, reg_sampler_code); + shader_addline(buffer, "TXP %s, %s, texture[%lu], %s;\n", + reg_dest, reg_coord, reg_sampler_code, tex_type); } else { - shader_addline(buffer, "TEX %s, %s, texture[%lu], 2D;\n", - reg_dest, reg_coord, reg_sampler_code); + shader_addline(buffer, "TEX %s, %s, texture[%lu], %s;\n", + reg_dest, reg_coord, reg_sampler_code, tex_type); } } diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index f5e3de50049..ebcc1607cb6 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -180,7 +180,8 @@ HRESULT shader_get_registers_used( shader_reg_maps* reg_maps, semantic* semantics_in, semantic* semantics_out, - CONST DWORD* pToken) { + CONST DWORD* pToken, + IWineD3DStateBlockImpl *stateBlock) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; @@ -299,8 +300,35 @@ HRESULT shader_get_registers_used( /* Fake sampler usage, only set reserved bit and ttype */ DWORD sampler_code = *pToken & D3DSP_REGNUM_MASK; - reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; - + + if(!stateBlock->textures[sampler_code]) { + ERR("No texture bound to sampler %ld\n", sampler_code); + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; + } else { + int texType = IWineD3DBaseTexture_GetTextureDimensions(stateBlock->textures[sampler_code]); + switch(texType) { + case GL_TEXTURE_1D: + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_1D; + break; + + case GL_TEXTURE_2D: + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; + break; + + case GL_TEXTURE_3D: + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_VOLUME; + break; + + case GLTEXTURECUBEMAP: + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_CUBE; + break; + + default: + ERR("Unexpected gl texture type found: %d\n", texType); + reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; + } + } + } else if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && (D3DSIO_TEXM3x3SPEC == curOpcode->opcode || D3DSIO_TEXM3x3VSPEC == curOpcode->opcode)) { diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index ab05dbb8332..814c40edf4d 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -917,8 +917,6 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) { IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; - HRESULT hr; - shader_reg_maps *reg_maps = &This->baseShader.reg_maps; TRACE("(%p) : pFunction %p\n", iface, pFunction); @@ -931,13 +929,6 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i list_init(&This->baseShader.constantsB); list_init(&This->baseShader.constantsI); - /* Second pass: figure out which registers are used, what the semantics are, etc.. */ - memset(reg_maps, 0, sizeof(shader_reg_maps)); - hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, - This->semantics_in, NULL, pFunction); - if (hr != WINED3D_OK) return hr; - /* FIXME: validate reg_maps against OpenGL */ - This->baseShader.shader_mode = wined3d_settings.ps_selected_mode; TRACE("(%p) : Copying the function\n", This); @@ -955,6 +946,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader *iface) { IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; CONST DWORD *function = This->baseShader.function; + shader_reg_maps *reg_maps = &This->baseShader.reg_maps; + HRESULT hr; TRACE("(%p) : function %p\n", iface, function); @@ -967,6 +960,13 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader return WINED3D_OK; } + /* Second pass: figure out which registers are used, what the semantics are, etc.. */ + memset(reg_maps, 0, sizeof(shader_reg_maps)); + hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, + This->semantics_in, NULL, This->baseShader.function, This->wineD3DDevice->stateBlock); + if (hr != WINED3D_OK) return hr; + /* FIXME: validate reg_maps against OpenGL */ + /* Generate the HW shader */ TRACE("(%p) : Generating hardware program\n", This); IWineD3DPixelShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function); diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 3427dff82f3..2f3de86b831 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -1183,7 +1183,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader /* Second pass: figure out registers used, semantics, etc.. */ memset(reg_maps, 0, sizeof(shader_reg_maps)); hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, - This->semantics_in, This->semantics_out, pFunction); + This->semantics_in, This->semantics_out, pFunction, This->wineD3DDevice->stateBlock); if (hr != WINED3D_OK) return hr; This->baseShader.shader_mode = wined3d_settings.vs_selected_mode; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bc8a9b5111c..f136ff21a01 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1599,7 +1599,8 @@ extern HRESULT shader_get_registers_used( shader_reg_maps* reg_maps, semantic* semantics_in, semantic* semantics_out, - CONST DWORD* pToken); + CONST DWORD* pToken, + IWineD3DStateBlockImpl *stateBlock); extern void shader_generate_glsl_declarations( IWineD3DBaseShader *iface,