From 2378108eb9de8d7dbe38ca7b4c5c05fcc7cb3bee Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 4 May 2009 09:49:27 +0200 Subject: [PATCH] wined3d: Create a frontend for parsing shaders. --- dlls/wined3d/arb_program_shader.c | 12 ++++-- dlls/wined3d/baseshader.c | 70 +++++++++++++++++-------------- dlls/wined3d/glsl_shader.c | 12 ++++-- dlls/wined3d/pixelshader.c | 8 ++-- dlls/wined3d/shader_sm1.c | 19 ++++++--- dlls/wined3d/vertexshader.c | 9 ++-- dlls/wined3d/wined3d_private.h | 44 +++++++++++-------- 7 files changed, 104 insertions(+), 70 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index ddc6da7634d..ea2db6cc2c4 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -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), diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 9c8ffbebe80..92122888534 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -295,9 +295,9 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh /* Note that this does not count the loop register * as an address register. */ -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) +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) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins; @@ -332,11 +332,11 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m UINT param_size; /* Skip comments */ - shader_sm1_read_comment(&pToken, &comment); + fe->shader_read_comment(&pToken, &comment); if (comment) continue; /* Fetch opcode */ - shader_sm1_read_opcode(&pToken, &ins, ¶m_size, shader_ins, shader_version); + fe->shader_read_opcode(&pToken, &ins, ¶m_size, shader_ins, shader_version); /* Unhandled opcode, and its parameters */ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) @@ -351,7 +351,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m { struct wined3d_shader_semantic semantic; - shader_sm1_read_semantic(&pToken, &semantic); + fe->shader_read_semantic(&pToken, &semantic); switch (semantic.reg.register_type) { @@ -388,7 +388,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant)); if (!lconst) return E_OUTOFMEMORY; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); lconst->idx = dst.register_idx; memcpy(lconst->value, pToken, 4 * sizeof(DWORD)); @@ -418,7 +418,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant)); if (!lconst) return E_OUTOFMEMORY; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); lconst->idx = dst.register_idx; memcpy(lconst->value, pToken, 4 * sizeof(DWORD)); @@ -434,7 +434,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant)); if (!lconst) return E_OUTOFMEMORY; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); lconst->idx = dst.register_idx; memcpy(lconst->value, pToken, sizeof(DWORD)); @@ -448,7 +448,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m { struct wined3d_shader_src_param src, rel_addr; - shader_sm1_read_src_param(&pToken, &src, &rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src, &rel_addr, shader_version); /* Rep and Loop always use an integer constant for the control parameters */ if (ins.handler_idx == WINED3DSIH_REP) @@ -457,7 +457,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m } else { - shader_sm1_read_src_param(&pToken, &src, &rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src, &rel_addr, shader_version); reg_maps->integer_constants |= 1 << src.register_idx; } @@ -475,7 +475,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m { struct wined3d_shader_src_param src, rel_addr; - shader_sm1_read_src_param(&pToken, &src, &rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src, &rel_addr, shader_version); reg_maps->labels[src.register_idx] = 1; } /* Set texture, address, temporary registers */ @@ -495,7 +495,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m struct wined3d_shader_dst_param dst_param; struct wined3d_shader_src_param dst_rel_addr; - shader_sm1_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel @@ -563,7 +563,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m { struct wined3d_shader_src_param src_param, src_rel_addr; - shader_sm1_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); shader_record_register_usage(This, reg_maps, src_param.register_type, src_param.register_idx, !!src_param.rel_addr, pshader); } @@ -835,8 +835,9 @@ void shader_dump_src_param(const struct wined3d_shader_src_param *param, DWORD s /* Shared code in order to generate the bulk of the shader string. * NOTE: A description of how to parse tokens can be found on msdn */ -void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, - const shader_reg_maps* reg_maps, CONST DWORD* pFunction) +void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer, + const struct wined3d_shader_frontend *fe, const shader_reg_maps *reg_maps, + const DWORD *pFunction) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */ @@ -875,11 +876,11 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, UINT param_size; /* Skip comment tokens */ - shader_sm1_read_comment(&pToken, &comment); + fe->shader_read_comment(&pToken, &comment); if (comment) continue; /* Read opcode */ - shader_sm1_read_opcode(&pToken, &ins, ¶m_size, opcode_table, shader_version); + fe->shader_read_opcode(&pToken, &ins, ¶m_size, opcode_table, shader_version); /* Unknown opcode and its parameters */ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) @@ -914,7 +915,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, } /* Destination token */ - if (ins.dst_count) shader_sm1_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); + if (ins.dst_count) fe->shader_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); /* Predication token */ if (ins.predicate) ins.predicate = *pToken++; @@ -922,7 +923,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, /* Other source tokens */ for (i = 0; i < ins.src_count; ++i) { - shader_sm1_read_src_param(&pToken, &src_param[i], &src_rel_addr[i], shader_version); + fe->shader_read_src_param(&pToken, &src_param[i], &src_rel_addr[i], shader_version); } /* Call appropriate function for output target */ @@ -960,7 +961,8 @@ static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst FIXME("_unrecognized_modifier(%#x)", mmask); } -void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table) +void shader_trace_init(const struct wined3d_shader_frontend *fe, + const DWORD *pFunction, const SHADER_OPCODE *opcode_table) { const DWORD* pToken = pFunction; DWORD shader_version; @@ -985,14 +987,14 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table UINT param_size; /* comment */ - shader_sm1_read_comment(&pToken, &comment); + fe->shader_read_comment(&pToken, &comment); if (comment) { TRACE("//%s\n", comment); continue; } - shader_sm1_read_opcode(&pToken, &ins, ¶m_size, opcode_table, shader_version); + fe->shader_read_opcode(&pToken, &ins, ¶m_size, opcode_table, shader_version); if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) { TRACE("Skipping unrecognized instruction.\n"); @@ -1004,7 +1006,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table { struct wined3d_shader_semantic semantic; - shader_sm1_read_semantic(&pToken, &semantic); + fe->shader_read_semantic(&pToken, &semantic); shader_dump_decl_usage(&semantic, shader_version); shader_dump_ins_modifiers(&semantic.reg); @@ -1016,7 +1018,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table struct wined3d_shader_dst_param dst; struct wined3d_shader_src_param rel_addr; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(dst.register_type, dst.register_idx), *(const float *)(pToken), @@ -1030,7 +1032,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table struct wined3d_shader_dst_param dst; struct wined3d_shader_src_param rel_addr; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); TRACE("defi i%u = %d, %d, %d, %d", dst.register_idx, *(pToken), @@ -1044,7 +1046,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table struct wined3d_shader_dst_param dst; struct wined3d_shader_src_param rel_addr; - shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst, &rel_addr, shader_version); TRACE("defb b%u = %s", dst.register_idx, *pToken ? "true" : "false"); ++pToken; @@ -1057,14 +1059,14 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table if (ins.dst_count) { - shader_sm1_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); + fe->shader_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); } /* Print out predication source token first - it follows * the destination token. */ if (ins.predicate) { - shader_sm1_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); TRACE("("); shader_dump_src_param(&src_param, shader_version); TRACE(") "); @@ -1107,7 +1109,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table /* Other source tokens */ for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i) { - shader_sm1_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); + fe->shader_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); TRACE(!i ? " " : ", "); shader_dump_src_param(&src_param, shader_version); } @@ -1140,11 +1142,15 @@ static void shader_none_destroy(IWineD3DBaseShader *iface) {} static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;} static void shader_none_free(IWineD3DDevice *iface) {} static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;} -static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) { +static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, const struct wined3d_shader_frontend *fe, + SHADER_BUFFER *buffer, const struct ps_compile_args *args) +{ FIXME("NONE shader backend asked to generate a pixel shader\n"); return 0; } -static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { +static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, const struct wined3d_shader_frontend *fe, + SHADER_BUFFER *buffer, const struct vs_compile_args *args) +{ FIXME("NONE shader backend asked to generate a vertex shader\n"); return 0; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 3fd950022df..302fd4eb2da 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -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"); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 6db17689155..33ac91c9ca7 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -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; diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c index ae490aee955..878ba72b4e5 100644 --- a/dlls/wined3d/shader_sm1.c +++ b/dlls/wined3d/shader_sm1.c @@ -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, +}; diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index b373caa7200..97584070315 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -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); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9b4a08651c4..95af9febfd9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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 */