wined3d: Create a frontend for parsing shaders.

This commit is contained in:
Henri Verbeet 2009-05-04 09:49:27 +02:00 committed by Alexandre Julliard
parent 5a7afd9b2a
commit 2378108eb9
7 changed files with 104 additions and 70 deletions

View File

@ -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 */ /* [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; IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const shader_reg_maps* reg_maps = &This->baseShader.reg_maps; const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function; 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); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
/* Base Shader Body */ /* 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) { if(args->srgb_correction) {
arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB"); 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; 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; IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const shader_reg_maps *reg_maps = &This->baseShader.reg_maps; const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function; CONST DWORD *function = This->baseShader.function;
@ -2115,7 +2119,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
} }
/* Base Shader Body */ /* 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 /* 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), * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),

View File

@ -295,9 +295,9 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
/* Note that this does not count the loop register /* Note that this does not count the loop register
* as an address register. */ * as an address register. */
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps, HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
const DWORD *byte_code) struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code)
{ {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins; 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; UINT param_size;
/* Skip comments */ /* Skip comments */
shader_sm1_read_comment(&pToken, &comment); fe->shader_read_comment(&pToken, &comment);
if (comment) continue; if (comment) continue;
/* Fetch opcode */ /* Fetch opcode */
shader_sm1_read_opcode(&pToken, &ins, &param_size, shader_ins, shader_version); fe->shader_read_opcode(&pToken, &ins, &param_size, shader_ins, shader_version);
/* Unhandled opcode, and its parameters */ /* Unhandled opcode, and its parameters */
if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) 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; struct wined3d_shader_semantic semantic;
shader_sm1_read_semantic(&pToken, &semantic); fe->shader_read_semantic(&pToken, &semantic);
switch (semantic.reg.register_type) 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)); local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY; 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; lconst->idx = dst.register_idx;
memcpy(lconst->value, pToken, 4 * sizeof(DWORD)); 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)); local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY; 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; lconst->idx = dst.register_idx;
memcpy(lconst->value, pToken, 4 * sizeof(DWORD)); 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)); local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY; 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; lconst->idx = dst.register_idx;
memcpy(lconst->value, pToken, sizeof(DWORD)); 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; 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 */ /* Rep and Loop always use an integer constant for the control parameters */
if (ins.handler_idx == WINED3DSIH_REP) if (ins.handler_idx == WINED3DSIH_REP)
@ -457,7 +457,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
} }
else 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; 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; 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; reg_maps->labels[src.register_idx] = 1;
} }
/* Set texture, address, temporary registers */ /* 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_dst_param dst_param;
struct wined3d_shader_src_param dst_rel_addr; 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 /* 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 * 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; 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, shader_record_register_usage(This, reg_maps, src_param.register_type,
src_param.register_idx, !!src_param.rel_addr, pshader); 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. /* 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 */ * NOTE: A description of how to parse tokens can be found on msdn */
void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const shader_reg_maps* reg_maps, CONST DWORD* pFunction) const struct wined3d_shader_frontend *fe, const shader_reg_maps *reg_maps,
const DWORD *pFunction)
{ {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */ 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; UINT param_size;
/* Skip comment tokens */ /* Skip comment tokens */
shader_sm1_read_comment(&pToken, &comment); fe->shader_read_comment(&pToken, &comment);
if (comment) continue; if (comment) continue;
/* Read opcode */ /* Read opcode */
shader_sm1_read_opcode(&pToken, &ins, &param_size, opcode_table, shader_version); fe->shader_read_opcode(&pToken, &ins, &param_size, opcode_table, shader_version);
/* Unknown opcode and its parameters */ /* Unknown opcode and its parameters */
if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
@ -914,7 +915,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
} }
/* Destination token */ /* 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 */ /* Predication token */
if (ins.predicate) ins.predicate = *pToken++; if (ins.predicate) ins.predicate = *pToken++;
@ -922,7 +923,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
/* Other source tokens */ /* Other source tokens */
for (i = 0; i < ins.src_count; ++i) 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 */ /* 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); 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; const DWORD* pToken = pFunction;
DWORD shader_version; DWORD shader_version;
@ -985,14 +987,14 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table
UINT param_size; UINT param_size;
/* comment */ /* comment */
shader_sm1_read_comment(&pToken, &comment); fe->shader_read_comment(&pToken, &comment);
if (comment) if (comment)
{ {
TRACE("//%s\n", comment); TRACE("//%s\n", comment);
continue; continue;
} }
shader_sm1_read_opcode(&pToken, &ins, &param_size, opcode_table, shader_version); fe->shader_read_opcode(&pToken, &ins, &param_size, opcode_table, shader_version);
if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
{ {
TRACE("Skipping unrecognized instruction.\n"); 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; 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_decl_usage(&semantic, shader_version);
shader_dump_ins_modifiers(&semantic.reg); 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_dst_param dst;
struct wined3d_shader_src_param rel_addr; 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), TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(dst.register_type, dst.register_idx),
*(const float *)(pToken), *(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_dst_param dst;
struct wined3d_shader_src_param rel_addr; 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, TRACE("defi i%u = %d, %d, %d, %d", dst.register_idx,
*(pToken), *(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_dst_param dst;
struct wined3d_shader_src_param rel_addr; 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"); TRACE("defb b%u = %s", dst.register_idx, *pToken ? "true" : "false");
++pToken; ++pToken;
@ -1057,14 +1059,14 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table
if (ins.dst_count) 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 /* Print out predication source token first - it follows
* the destination token. */ * the destination token. */
if (ins.predicate) 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("("); TRACE("(");
shader_dump_src_param(&src_param, shader_version); shader_dump_src_param(&src_param, shader_version);
TRACE(") "); TRACE(") ");
@ -1107,7 +1109,7 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table
/* Other source tokens */ /* Other source tokens */
for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i) 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 ? " " : ", "); TRACE(!i ? " " : ", ");
shader_dump_src_param(&src_param, shader_version); 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 HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
static void shader_none_free(IWineD3DDevice *iface) {} static void shader_none_free(IWineD3DDevice *iface) {}
static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;} 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"); FIXME("NONE shader backend asked to generate a pixel shader\n");
return 0; 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"); FIXME("NONE shader backend asked to generate a vertex shader\n");
return 0; return 0;
} }

View File

@ -3984,7 +3984,9 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
return FALSE; 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; IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps; const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function; CONST DWORD *function = This->baseShader.function;
@ -4015,7 +4017,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
} }
/* Base Shader Body */ /* 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 */ /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (reg_maps->shader_version < WINED3DPS_VERSION(2,0)) 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; 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; IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps; const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function; 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); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
/* Base Shader Body */ /* 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 */ /* Unpack 3.0 outputs */
if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n"); if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");

View File

@ -306,7 +306,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
TRACE("(%p) : pFunction %p\n", iface, pFunction); TRACE("(%p) : pFunction %p\n", iface, pFunction);
/* First pass: trace shader */ /* 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 */ /* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF); list_init(&This->baseShader.constantsF);
@ -314,7 +314,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
list_init(&This->baseShader.constantsI); list_init(&This->baseShader.constantsI);
/* Second pass: figure out which registers are used, what the semantics are, etc.. */ /* 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; if (FAILED(hr)) return hr;
pshader_set_limits(This); pshader_set_limits(This);
@ -432,7 +433,8 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
TRACE("(%p) : Generating hardware program\n", This); TRACE("(%p) : Generating hardware program\n", This);
This->cur_args = args; This->cur_args = args;
shader_buffer_init(&buffer); 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); shader_buffer_free(&buffer);
This->cur_args = NULL; This->cur_args = NULL;

View File

@ -219,7 +219,7 @@ static int shader_skip_unrecognized(const DWORD *ptr, DWORD shader_version)
return tokens_read; 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_table, DWORD shader_version)
{ {
const SHADER_OPCODE *opcode_info; 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); *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) struct wined3d_shader_src_param *src_rel_addr, DWORD shader_version)
{ {
DWORD token, addr_token; 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) struct wined3d_shader_src_param *dst_rel_addr, DWORD shader_version)
{ {
DWORD token, addr_token; 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 usage_token = *(*ptr)++;
DWORD dst_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); 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; DWORD token = **ptr;
@ -302,3 +302,12 @@ void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
*comment = (const char *)++(*ptr); *comment = (const char *)++(*ptr);
*ptr += (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT; *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,
};

View File

@ -319,7 +319,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
TRACE("(%p) : pFunction %p\n", iface, pFunction); TRACE("(%p) : pFunction %p\n", iface, pFunction);
/* First pass: trace shader */ /* 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 */ /* Initialize immediate constant lists */
list_init(&This->baseShader.constantsF); list_init(&This->baseShader.constantsF);
@ -329,8 +329,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
/* Second pass: figure out registers used, semantics, etc.. */ /* Second pass: figure out registers used, semantics, etc.. */
This->min_rel_offset = GL_LIMITS(vshader_constantsF); This->min_rel_offset = GL_LIMITS(vshader_constantsF);
This->max_rel_offset = 0; This->max_rel_offset = 0;
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, hr = shader_get_registers_used((IWineD3DBaseShader*) This, &sm1_shader_frontend,
This->semantics_in, This->semantics_out, pFunction); reg_maps, This->semantics_in, This->semantics_out, pFunction);
if (hr != WINED3D_OK) return hr; if (hr != WINED3D_OK) return hr;
vshader_set_limits(This); vshader_set_limits(This);
@ -411,7 +411,8 @@ static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct
TRACE("(%p) : Generating hardware program\n", This); TRACE("(%p) : Generating hardware program\n", This);
shader_buffer_init(&buffer); shader_buffer_init(&buffer);
This->cur_args = args; 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; This->cur_args = NULL;
shader_buffer_free(&buffer); shader_buffer_free(&buffer);

View File

@ -674,6 +674,20 @@ struct wined3d_shader_semantic
struct wined3d_shader_dst_param reg; 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 *); typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
struct shader_caps { struct shader_caps {
@ -762,8 +776,10 @@ typedef struct {
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface); void (*shader_free_private)(IWineD3DDevice *iface);
BOOL (*shader_dirtifyable_constants)(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_pshader)(IWineD3DPixelShader *iface, const struct wined3d_shader_frontend *fe,
GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args); 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); 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); BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
} shader_backend_t; } shader_backend_t;
@ -2532,15 +2548,16 @@ void shader_buffer_free(struct SHADER_BUFFER *buffer);
void shader_cleanup(IWineD3DBaseShader *iface); void shader_cleanup(IWineD3DBaseShader *iface);
void shader_dump_src_param(const struct wined3d_shader_src_param *param, DWORD shader_version); 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); 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, void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, const struct wined3d_shader_frontend *fe, const shader_reg_maps *reg_maps,
const DWORD *byte_code); 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, void shader_init(struct IWineD3DBaseShaderClass *shader,
IWineD3DDevice *device, const SHADER_OPCODE *instruction_table); IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table); void shader_trace_init(const struct wined3d_shader_frontend *fe,
const DWORD *pFunction, const SHADER_OPCODE *opcode_table);
extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
const shader_reg_maps *reg_maps, const DWORD *pFunction);
static inline BOOL shader_is_pshader_version(DWORD token) { static inline BOOL shader_is_pshader_version(DWORD token) {
return 0xFFFF0000 == (token & 0xFFFF0000); 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 * IDirect3DVertexShader implementation structures
*/ */