wined3d: Don't reparse the entire shader just to update the sampler types.
Henri Verbeet
hverbeet at codeweavers.com
Fri Dec 12 02:33:51 CST 2008
---
dlls/wined3d/baseshader.c | 32 ++---------------
dlls/wined3d/device.c | 3 +-
dlls/wined3d/pixelshader.c | 76 +++++++++++++++++++++++++---------------
dlls/wined3d/vertexshader.c | 2 +-
dlls/wined3d/wined3d_private.h | 12 ++----
include/wine/wined3d.idl | 2 -
6 files changed, 58 insertions(+), 69 deletions(-)
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 8d6c28c..9bac931 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -207,8 +207,7 @@ static void shader_delete_constant_list(struct list* clist) {
* as an address register. */
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
- struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code,
- IWineD3DStateBlockImpl *stateBlock)
+ struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code)
{
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
@@ -384,33 +383,8 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
/* Fake sampler usage, only set reserved bit and ttype */
DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
- if(!stateBlock->textures[sampler_code]) {
- ERR("No texture bound to sampler %d\n", sampler_code);
- reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
- } else {
- int texType = IWineD3DBaseTexture_GetTextureDimensions(stateBlock->textures[sampler_code]);
- switch(texType) {
- /* We have to select between texture rectangles and 2D textures later because 2.0 and
- * 3.0 shaders only have WINED3DSTT_2D as well
- */
- case GL_TEXTURE_RECTANGLE_ARB:
- 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 GL_TEXTURE_CUBE_MAP_ARB:
- 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;
- }
- }
+ TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
+ reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
/* texbem is only valid with < 1.4 pixel shaders */
if(WINED3DSIO_TEXBEM == curOpcode->opcode ||
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 836ad3b..0541c59 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3862,7 +3862,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
IWineD3DPixelShaderImpl *pshader = (IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader;
/* Make sure the shader's reg_maps are up to date. This is only relevant for 1.x pixelshaders. */
- IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *)pshader);
+ pixelshader_update_samplers(&pshader->baseShader.reg_maps, This->stateBlock->textures,
+ pshader->baseShader.hex_version);
pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
}
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index c5f3c3e..200a2bc 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -332,8 +332,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
/* 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, deviceImpl->stateBlock);
+ hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction);
if (FAILED(hr)) return hr;
pshader_set_limits(This);
@@ -396,19 +395,60 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
return WINED3D_OK;
}
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures,
+ DWORD shader_version)
+{
+ DWORD *samplers = reg_maps->samplers;
+ unsigned int i;
+
+ if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return;
+
+ for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
+ {
+ /* We don't sample from this sampler */
+ if (!samplers[i]) continue;
+
+ if (!textures[i])
+ {
+ ERR("No texture bound to sampler %u, using 2D\n", i);
+ samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+ continue;
+ }
+
+ switch (IWineD3DBaseTexture_GetTextureDimensions(textures[i]))
+ {
+ case GL_TEXTURE_RECTANGLE_ARB:
+ case GL_TEXTURE_2D:
+ /* We have to select between texture rectangles and 2D textures later because 2.0 and
+ * 3.0 shaders only have WINED3DSTT_2D as well */
+ samplers[i] = (1 << 31) | WINED3DSTT_2D;
+ break;
+
+ case GL_TEXTURE_3D:
+ samplers[i] = (1 << 31) | WINED3DSTT_VOLUME;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ samplers[i] = (1 << 31) | WINED3DSTT_CUBE;
+ break;
+
+ default:
+ FIXME("Unrecognized texture type %#x, using 2D\n",
+ IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
+ samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+ }
+ }
+}
+
static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
{
CONST DWORD *function = This->baseShader.function;
- HRESULT hr;
GLuint retval;
TRACE("(%p) : function %p\n", This, function);
- hr = IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *) This);
- if(FAILED(hr)) {
- ERR("Failed to update sampler information\n");
- return 0;
- }
+ pixelshader_update_samplers(&This->baseShader.reg_maps,
+ ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures, This->baseShader.hex_version);
/* Reset fields tracking stateblock values being hardcoded in the shader */
This->baseShader.num_sampled_samplers = 0;
@@ -422,25 +462,6 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
return retval;
}
-static HRESULT WINAPI IWineD3DPixelShaderImpl_UpdateSamplers(IWineD3DPixelShader *iface) {
- IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
-
- if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) {
- IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
- shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
- HRESULT hr;
-
- /* 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, deviceImpl->stateBlock);
- return hr;
- /* FIXME: validate reg_maps against OpenGL */
- } else {
- return WINED3D_OK;
- }
-}
-
const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
{
/*** IUnknown methods ***/
@@ -452,7 +473,6 @@ const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
/*** IWineD3DBaseShader methods ***/
IWineD3DPixelShaderImpl_SetFunction,
/*** IWineD3DPixelShader methods ***/
- IWineD3DPixelShaderImpl_UpdateSamplers,
IWineD3DPixelShaderImpl_GetDevice,
IWineD3DPixelShaderImpl_GetFunction
};
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 529fe7a..ea8781f 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -447,7 +447,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
This->max_rel_offset = 0;
memset(reg_maps, 0, sizeof(shader_reg_maps));
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
- This->semantics_in, This->semantics_out, pFunction, NULL);
+ This->semantics_in, This->semantics_out, pFunction);
if (hr != WINED3D_OK) return hr;
vshader_set_limits(This);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fe5569a..8cb8cea 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2230,16 +2230,10 @@ typedef struct IWineD3DBaseShaderImpl {
void shader_buffer_init(struct SHADER_BUFFER *buffer);
void shader_buffer_free(struct SHADER_BUFFER *buffer);
void shader_cleanup(IWineD3DBaseShader *iface);
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
+ struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code);
void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
-extern HRESULT shader_get_registers_used(
- IWineD3DBaseShader *iface,
- shader_reg_maps* reg_maps,
- semantic* semantics_in,
- semantic* semantics_out,
- CONST DWORD* pToken,
- IWineD3DStateBlockImpl *stateBlock);
-
extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const shader_reg_maps *reg_maps, const DWORD *pFunction);
@@ -2407,6 +2401,8 @@ extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args);
void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures,
+ DWORD shader_version);
/* sRGB correction constants */
static const float srgb_cmp = 0.0031308;
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index abb0d3b..39ba598 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2825,8 +2825,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
]
interface IWineD3DPixelShader : IWineD3DBaseShader
{
- HRESULT UpdateSamplers(
- );
HRESULT GetDevice(
[out] IWineD3DDevice **device
);
--
1.5.6.4
--------------030900030602010403050708--
More information about the wine-patches
mailing list