wined3d: Don't reparse the entire shader just to update the sampler types.

This commit is contained in:
Henri Verbeet 2008-12-12 09:33:51 +01:00 committed by Alexandre Julliard
parent 8777a83467
commit fb475c7c29
6 changed files with 58 additions and 69 deletions

View File

@ -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 ||

View File

@ -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;
}

View File

@ -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
};

View File

@ -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);

View File

@ -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;

View File

@ -2825,8 +2825,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
]
interface IWineD3DPixelShader : IWineD3DBaseShader
{
HRESULT UpdateSamplers(
);
HRESULT GetDevice(
[out] IWineD3DDevice **device
);