wined3d: Select the frontend based on the version token.

This commit is contained in:
Henri Verbeet 2009-05-04 09:49:27 +02:00 committed by Alexandre Julliard
parent 5f96c0083a
commit dddd1f0211
4 changed files with 56 additions and 9 deletions

View File

@ -119,6 +119,23 @@ static const char *shader_opcode_names[] =
/* WINED3DSIH_TEXREG2RGB */ "texreg2rgb",
};
#define WINED3D_SM1_VS 0xfffe
#define WINED3D_SM1_PS 0xffff
const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
{
switch (version_token >> 16)
{
case WINED3D_SM1_VS:
case WINED3D_SM1_PS:
return &sm1_shader_frontend;
default:
FIXME("Unrecognised version token %#x\n", version_token);
return NULL;
}
}
static inline BOOL shader_is_version_token(DWORD token) {
return shader_is_pshader_version(token) ||
shader_is_vshader_version(token);

View File

@ -301,12 +301,20 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
unsigned int i, highest_reg_used = 0, num_regs_used = 0;
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
const struct wined3d_shader_frontend *fe;
HRESULT hr;
TRACE("(%p) : pFunction %p\n", iface, pFunction);
fe = shader_select_frontend(*pFunction);
if (!fe)
{
FIXME("Unable to find frontend for shader.\n");
return WINED3DERR_INVALIDCALL;
}
/* First pass: trace shader */
if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
if (TRACE_ON(d3d_shader)) shader_trace_init(fe, pFunction, This->baseShader.shader_ins);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
@ -314,8 +322,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
list_init(&This->baseShader.constantsI);
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
hr = shader_get_registers_used((IWineD3DBaseShader *)This, &sm1_shader_frontend,
reg_maps, This->semantics_in, NULL, pFunction);
hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction);
if (FAILED(hr)) return hr;
pshader_set_limits(This);
@ -422,10 +429,18 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
CONST DWORD *function = This->baseShader.function;
GLuint retval;
SHADER_BUFFER buffer;
const struct wined3d_shader_frontend *fe;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
TRACE("(%p) : function %p\n", This, function);
fe = shader_select_frontend(This->baseShader.reg_maps.shader_version);
if (!fe)
{
FIXME("Unable to find frontend for shader.\n");
return WINED3DERR_INVALIDCALL;
}
pixelshader_update_samplers(&This->baseShader.reg_maps,
((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
@ -433,8 +448,7 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
TRACE("(%p) : Generating hardware program\n", This);
This->cur_args = args;
shader_buffer_init(&buffer);
retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This,
&sm1_shader_frontend, &buffer, args);
retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, fe, &buffer, args);
shader_buffer_free(&buffer);
This->cur_args = NULL;

View File

@ -313,13 +313,21 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
const struct wined3d_shader_frontend *fe;
HRESULT hr;
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
TRACE("(%p) : pFunction %p\n", iface, pFunction);
fe = shader_select_frontend(*pFunction);
if (!fe)
{
FIXME("Unable to find frontend for shader.\n");
return WINED3DERR_INVALIDCALL;
}
/* First pass: trace shader */
if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
if (TRACE_ON(d3d_shader)) shader_trace_init(fe, pFunction, This->baseShader.shader_ins);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
@ -329,7 +337,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
/* Second pass: figure out registers used, semantics, etc.. */
This->min_rel_offset = GL_LIMITS(vshader_constantsF);
This->max_rel_offset = 0;
hr = shader_get_registers_used((IWineD3DBaseShader*) This, &sm1_shader_frontend,
hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
reg_maps, This->semantics_in, This->semantics_out, pFunction);
if (hr != WINED3D_OK) return hr;
@ -404,15 +412,22 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) {
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
const struct wined3d_shader_frontend *fe;
SHADER_BUFFER buffer;
GLuint ret;
fe = shader_select_frontend(This->baseShader.reg_maps.shader_version);
if (!fe)
{
FIXME("Unable to find frontend for shader.\n");
return WINED3DERR_INVALIDCALL;
}
/* Generate the HW shader */
TRACE("(%p) : Generating hardware program\n", This);
shader_buffer_init(&buffer);
This->cur_args = args;
ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This,
&sm1_shader_frontend, &buffer, args);
ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This, fe, &buffer, args);
This->cur_args = NULL;
shader_buffer_free(&buffer);

View File

@ -2555,6 +2555,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code);
void shader_init(struct IWineD3DBaseShaderClass *shader,
IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
void shader_trace_init(const struct wined3d_shader_frontend *fe,
const DWORD *pFunction, const SHADER_OPCODE *opcode_table);