diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index b519fe54008..e3f63118ff6 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -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); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 33ac91c9ca7..c4693a25a50 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -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; diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 97584070315..c71b612d2f3 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -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); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b22c1910e9e..09d8f9d6e80 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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);