Commit 2378108e authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Create a frontend for parsing shaders.

parent 5a7afd9b
......@@ -1975,7 +1975,9 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
/* [0.0;1.0] clamping. Not needed, this is done implicitly */
}
static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct ps_compile_args *args)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
......@@ -2024,7 +2026,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
shader_generate_main((IWineD3DBaseShader *)This, buffer, fe, reg_maps, function);
if(args->srgb_correction) {
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
......@@ -2063,7 +2065,9 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
return retval;
}
static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct vs_compile_args *args)
{
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
......@@ -2115,7 +2119,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
}
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
shader_generate_main((IWineD3DBaseShader *)This, buffer, fe, reg_maps, function);
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
......
......@@ -3984,7 +3984,9 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
return FALSE;
}
static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct ps_compile_args *args)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
......@@ -4015,7 +4017,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
}
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
shader_generate_main((IWineD3DBaseShader *)This, buffer, fe, reg_maps, function);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (reg_maps->shader_version < WINED3DPS_VERSION(2,0))
......@@ -4083,7 +4085,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
return shader_obj;
}
static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct vs_compile_args *args)
{
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
......@@ -4098,7 +4102,7 @@ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_B
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
shader_generate_main((IWineD3DBaseShader*)This, buffer, fe, reg_maps, function);
/* Unpack 3.0 outputs */
if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");
......
......@@ -306,7 +306,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
TRACE("(%p) : pFunction %p\n", iface, pFunction);
/* First pass: trace shader */
if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
......@@ -314,7 +314,8 @@ 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, reg_maps, This->semantics_in, NULL, pFunction);
hr = shader_get_registers_used((IWineD3DBaseShader *)This, &sm1_shader_frontend,
reg_maps, This->semantics_in, NULL, pFunction);
if (FAILED(hr)) return hr;
pshader_set_limits(This);
......@@ -432,7 +433,8 @@ 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, &buffer, args);
retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This,
&sm1_shader_frontend, &buffer, args);
shader_buffer_free(&buffer);
This->cur_args = NULL;
......
......@@ -219,7 +219,7 @@ static int shader_skip_unrecognized(const DWORD *ptr, DWORD shader_version)
return tokens_read;
}
void shader_sm1_read_opcode(const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size,
static void shader_sm1_read_opcode(const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size,
const SHADER_OPCODE *opcode_table, DWORD shader_version)
{
const SHADER_OPCODE *opcode_info;
......@@ -244,7 +244,7 @@ void shader_sm1_read_opcode(const DWORD **ptr, struct wined3d_shader_instruction
*param_size = shader_skip_opcode(opcode_info, opcode_token, shader_version);
}
void shader_sm1_read_src_param(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
static void shader_sm1_read_src_param(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
struct wined3d_shader_src_param *src_rel_addr, DWORD shader_version)
{
DWORD token, addr_token;
......@@ -261,7 +261,7 @@ void shader_sm1_read_src_param(const DWORD **ptr, struct wined3d_shader_src_para
}
}
void shader_sm1_read_dst_param(const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
static void shader_sm1_read_dst_param(const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
struct wined3d_shader_src_param *dst_rel_addr, DWORD shader_version)
{
DWORD token, addr_token;
......@@ -278,7 +278,7 @@ void shader_sm1_read_dst_param(const DWORD **ptr, struct wined3d_shader_dst_para
}
}
void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
{
DWORD usage_token = *(*ptr)++;
DWORD dst_token = *(*ptr)++;
......@@ -289,7 +289,7 @@ void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}
void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
static void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
{
DWORD token = **ptr;
......@@ -302,3 +302,12 @@ void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
*comment = (const char *)++(*ptr);
*ptr += (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
}
const struct wined3d_shader_frontend sm1_shader_frontend =
{
shader_sm1_read_opcode,
shader_sm1_read_src_param,
shader_sm1_read_dst_param,
shader_sm1_read_semantic,
shader_sm1_read_comment,
};
......@@ -319,7 +319,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
TRACE("(%p) : pFunction %p\n", iface, pFunction);
/* First pass: trace shader */
if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
if (TRACE_ON(d3d_shader)) shader_trace_init(&sm1_shader_frontend, pFunction, This->baseShader.shader_ins);
/* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF);
......@@ -329,8 +329,8 @@ 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, reg_maps,
This->semantics_in, This->semantics_out, pFunction);
hr = shader_get_registers_used((IWineD3DBaseShader*) This, &sm1_shader_frontend,
reg_maps, This->semantics_in, This->semantics_out, pFunction);
if (hr != WINED3D_OK) return hr;
vshader_set_limits(This);
......@@ -411,7 +411,8 @@ static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct
TRACE("(%p) : Generating hardware program\n", This);
shader_buffer_init(&buffer);
This->cur_args = args;
ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This, &buffer, args);
ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This,
&sm1_shader_frontend, &buffer, args);
This->cur_args = NULL;
shader_buffer_free(&buffer);
......
......@@ -674,6 +674,20 @@ struct wined3d_shader_semantic
struct wined3d_shader_dst_param reg;
};
struct wined3d_shader_frontend
{
void (*shader_read_opcode)(const DWORD **ptr, struct wined3d_shader_instruction *ins,
UINT *param_size, const SHADER_OPCODE *opcode_table, DWORD shader_version);
void (*shader_read_src_param)(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
struct wined3d_shader_src_param *src_rel_addr, DWORD shader_version);
void (*shader_read_dst_param)(const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
struct wined3d_shader_src_param *dst_rel_addr, DWORD shader_version);
void (*shader_read_semantic)(const DWORD **ptr, struct wined3d_shader_semantic *semantic);
void (*shader_read_comment)(const DWORD **ptr, const char **comment);
};
extern const struct wined3d_shader_frontend sm1_shader_frontend;
typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
struct shader_caps {
......@@ -762,8 +776,10 @@ typedef struct {
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface);
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args);
GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct ps_compile_args *args);
GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, const struct wined3d_shader_frontend *fe,
SHADER_BUFFER *buffer, const struct vs_compile_args *args);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
} shader_backend_t;
......@@ -2532,15 +2548,16 @@ void shader_buffer_free(struct SHADER_BUFFER *buffer);
void shader_cleanup(IWineD3DBaseShader *iface);
void shader_dump_src_param(const struct wined3d_shader_src_param *param, DWORD shader_version);
void shader_dump_dst_param(const struct wined3d_shader_dst_param *param, DWORD shader_version);
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
const DWORD *byte_code);
void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const struct wined3d_shader_frontend *fe, const shader_reg_maps *reg_maps,
const DWORD *pFunction);
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code);
void shader_init(struct IWineD3DBaseShaderClass *shader,
IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const shader_reg_maps *reg_maps, const DWORD *pFunction);
void shader_trace_init(const struct wined3d_shader_frontend *fe,
const DWORD *pFunction, const SHADER_OPCODE *opcode_table);
static inline BOOL shader_is_pshader_version(DWORD token) {
return 0xFFFF0000 == (token & 0xFFFF0000);
......@@ -2593,15 +2610,6 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD
}
void shader_sm1_read_opcode(const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size,
const SHADER_OPCODE *opcode_table, DWORD shader_version);
void shader_sm1_read_src_param(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
struct wined3d_shader_src_param *src_rel_addr, DWORD shader_version);
void shader_sm1_read_dst_param(const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
struct wined3d_shader_src_param *dst_rel_addr, DWORD shader_version);
void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic);
void shader_sm1_read_comment(const DWORD **ptr, const char **comment);
/*****************************************************************************
* IDirect3DVertexShader implementation structures
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment