wined3d: Don't reparse the entire shader just to update the sampler types.
This commit is contained in:
parent
8777a83467
commit
fb475c7c29
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2825,8 +2825,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
|
|||
]
|
||||
interface IWineD3DPixelShader : IWineD3DBaseShader
|
||||
{
|
||||
HRESULT UpdateSamplers(
|
||||
);
|
||||
HRESULT GetDevice(
|
||||
[out] IWineD3DDevice **device
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue