From ca70d13af4710c0cb924638c224c0643caeb94e5 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Fri, 9 Jun 2006 03:33:33 -0400 Subject: [PATCH] wined3d: Unified float constant register mapping between ARB pixel and vertex shaders. - Got rid of the separate constant maps. - Side effect of this is that the map is a bit larger for pixel shaders than it needs to be --- dlls/wined3d/baseshader.c | 20 ++++++++++++++- dlls/wined3d/pixelshader.c | 46 ++++++++++------------------------ dlls/wined3d/vertexshader.c | 42 +++++++++++-------------------- dlls/wined3d/wined3d_private.h | 21 +++------------- 4 files changed, 50 insertions(+), 79 deletions(-) diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 5a585afd651..da81351994b 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -614,9 +614,11 @@ void generate_base_shader( DWORD opcode_token; DWORD i; shader_reg_maps reg_maps; + SHADER_OPCODE_ARG hw_arg; + + memset(®_maps, 0, sizeof(shader_reg_maps)); /* Initialize current parsing state */ - SHADER_OPCODE_ARG hw_arg; hw_arg.shader = iface; hw_arg.buffer = buffer; hw_arg.reg_maps = ®_maps; @@ -746,4 +748,20 @@ void shader_dump_ins_modifiers(const DWORD output) { FIXME("_unrecognized_modifier(%#lx)", mmask >> D3DSP_DSTMOD_SHIFT); } +/** Process the D3DSIO_DCL opcode into an ARB string - creates a local vec4 + * float constant, and stores it's usage on the regmaps. */ +void shader_hw_def(SHADER_OPCODE_ARG* arg) { + + DWORD reg = arg->dst; + + shader_addline(arg->buffer, + "PARAM C%lu = { %f, %f, %f, %f };\n", reg & 0xFF, + *((const float *)(arg->src + 0)), + *((const float *)(arg->src + 1)), + *((const float *)(arg->src + 2)), + *((const float *)(arg->src + 3)) ); + + arg->reg_maps->constantsF[reg] = 1; +} + /* TODO: Move other shared code here */ diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index f40411549a2..4c52a25b6c8 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -621,7 +621,6 @@ void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg); void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg); void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg); void pshader_hw_texbem(SHADER_OPCODE_ARG* arg); -void pshader_hw_def(SHADER_OPCODE_ARG* arg); void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg); void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg); void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg); @@ -705,7 +704,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 1, pshader_label, NULL, NULL, 0, 0}, /* Constant definitions */ - {D3DSIO_DEF, "def", "undefined", 5, pshader_def, pshader_hw_def, NULL, 0, 0}, + {D3DSIO_DEF, "def", "undefined", 5, pshader_def, shader_hw_def, NULL, 0, 0}, {D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 2, pshader_defb, NULL, NULL, 0, 0}, {D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 5, pshader_defi, NULL, NULL, 0, 0}, @@ -744,7 +743,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {0, NULL, NULL, 0, NULL, NULL, 0, 0} }; -inline static void get_register_name(const DWORD param, char* regstr, char constants[WINED3D_PSHADER_MAX_CONSTANTS]) { +inline static void get_register_name(const DWORD param, char* regstr, CHAR *constants) { DWORD reg = param & D3DSP_REGNUM_MASK; DWORD regtype = shader_get_regtype(param); @@ -868,7 +867,7 @@ static void pshader_gen_input_modifier_line ( const DWORD instr, int tmpreg, char *outregstr, - char constants[WINED3D_PSHADER_MAX_CONSTANTS]) { + CHAR *constants) { /* Generate a line that does the input modifier computation and return the input register to use */ char regstr[256]; @@ -991,7 +990,6 @@ void pshader_set_version( /* FIXME: fix CMP/CND, get rid of this switch */ void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { - IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; DWORD dst = arg->dst; @@ -1033,10 +1031,10 @@ void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { /* Generate input register names (with modifiers) */ for (i = 1; i < curOpcode->num_params; ++i) - pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i], This->constants); + pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i], arg->reg_maps->constantsF); /* Handle output register */ - get_register_name(dst, output_rname, This->constants); + get_register_name(dst, output_rname, arg->reg_maps->constantsF); strcpy(operands[0], output_rname); get_write_mask(dst, output_wmask); strcat(operands[0], output_wmask); @@ -1086,14 +1084,14 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { /* All versions have a destination register */ reg_dest_code = dst & D3DSP_REGNUM_MASK; - get_register_name(dst, reg_dest, This->constants); + get_register_name(dst, reg_dest, arg->reg_maps->constantsF); /* 1.0-1.3: Use destination register as coordinate source. 2.0+: Use provided coordinate source register. */ if (version < 14) strcpy(reg_coord, reg_dest); else - pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, This->constants); + pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF); /* 1.0-1.4: Use destination register number as texture code. 2.0+: Use provided sampler number as texure code. */ @@ -1160,41 +1158,23 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) { shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg1, reg1); } -void pshader_hw_def(SHADER_OPCODE_ARG* arg) { - - IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; - DWORD reg = arg->dst & D3DSP_REGNUM_MASK; - SHADER_BUFFER* buffer = arg->buffer; - - shader_addline(buffer, - "PARAM C%lu = { %f, %f, %f, %f };\n", reg, - *((float*) (arg->src + 0)), - *((float*) (arg->src + 1)), - *((float*) (arg->src + 2)), - *((float*) (arg->src + 3)) ); - - shader->constants[reg] = 1; -} - void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) { - IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; DWORD reg = arg->dst & D3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = arg->buffer; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.x, T%lu, %s;\n", reg, src0_name); } void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) { - IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; DWORD reg = arg->dst & D3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = arg->buffer; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.y, T%lu, %s;\n", reg, src0_name); shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg); } @@ -1207,7 +1187,7 @@ void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) { SHADER_PARSE_STATE current_state = shader->baseShader.parse_state; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x' + current_state.current_row, reg, src0_name); current_state.texcoord_w[current_state.current_row++] = reg; } @@ -1220,7 +1200,7 @@ void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) { SHADER_PARSE_STATE current_state = shader->baseShader.parse_state; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name); /* Cubemap textures will be more used than 3D ones. */ @@ -1236,7 +1216,7 @@ void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) { SHADER_PARSE_STATE current_state = shader->baseShader.parse_state; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name); /* Construct the eye-ray vector from w coordinates */ @@ -1263,7 +1243,7 @@ void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char src0_name[50]; - pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, shader->constants); + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF); shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name); /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */ diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 09d1f788cc7..908171e229a 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -480,7 +480,6 @@ void vshader_texldl(WINED3DSHADERVECTOR* d) { /* Prototype */ void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg); void vshader_hw_dcl(SHADER_OPCODE_ARG* arg); -void vshader_hw_def(SHADER_OPCODE_ARG* arg); void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg); /** @@ -543,7 +542,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { {D3DSIO_DCL, "dcl", NULL, 2, vshader_dcl, vshader_hw_dcl, NULL, 0, 0}, /* Constant definitions */ - {D3DSIO_DEF, "def", NULL, 5, vshader_def, vshader_hw_def, NULL, 0, 0}, + {D3DSIO_DEF, "def", NULL, 5, vshader_def, shader_hw_def, NULL, 0, 0}, {D3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 2, vshader_defb, NULL, NULL, 0, 0}, {D3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 5, vshader_defi, NULL, NULL, 0, 0}, @@ -631,7 +630,10 @@ inline static void vshader_program_add_input_param_swizzle(const DWORD param, in } } -inline static void vshader_program_add_param(IWineD3DVertexShaderImpl *This, const DWORD param, BOOL is_input, char *hwLine) { +inline static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) { + + IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)arg->shader; + /* oPos, oFog and oPts in D3D */ static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" }; @@ -667,7 +669,7 @@ inline static void vshader_program_add_param(IWineD3DVertexShaderImpl *This, con break; case D3DSPR_CONST: /* FIXME: some constants are named so we need a constants map*/ - if (This->constantsUsedBitmap[reg] == VS_CONSTANT_CONSTANT) { + if (arg->reg_maps->constantsF[reg]) { if (param & D3DVS_ADDRMODE_RELATIVE) { FIXME("Relative addressing not expected for a named constant %lu\n", reg); } @@ -879,7 +881,6 @@ void vshader_set_version( /* Map the opcode 1-to-1 to the GL code */ void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { - IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader; CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; DWORD dst = arg->dst; @@ -895,10 +896,10 @@ void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { strcpy(tmpLine, curOpcode->glname); if (curOpcode->num_params > 0) { - vshader_program_add_param(This, dst, FALSE, tmpLine); + vshader_program_add_param(arg, dst, FALSE, tmpLine); for (i = 1; i < curOpcode->num_params; ++i) { strcat(tmpLine, ","); - vshader_program_add_param(This, src[i-1], TRUE, tmpLine); + vshader_program_add_param(arg, src[i-1], TRUE, tmpLine); } } shader_addline(buffer, "%s;\n", tmpLine); @@ -972,29 +973,13 @@ void vshader_hw_dcl(SHADER_OPCODE_ARG* arg) { } { sprintf(tmpLine, "ATTRIB "); - vshader_program_add_param(This, dst, FALSE, tmpLine); + vshader_program_add_param(arg, dst, FALSE, tmpLine); if (This->namedArrays) shader_addline(buffer, "%s = %s;\n", tmpLine, attribName); } } } -void vshader_hw_def(SHADER_OPCODE_ARG* arg) { - - IWineD3DVertexShaderImpl* shader = (IWineD3DVertexShaderImpl*) arg->shader; - SHADER_BUFFER* buffer = arg->buffer; - DWORD reg = arg->dst; - - shader_addline(buffer, - "PARAM C%lu = { %f, %f, %f, %f };\n", reg & 0xFF, - *((const float *)(arg->src + 0)), - *((const float *)(arg->src + 1)), - *((const float *)(arg->src + 2)), - *((const float *)(arg->src + 3)) ); - - shader->constantsUsedBitmap[reg & 0xFF] = VS_CONSTANT_CONSTANT; -} - /** Handles transforming all D3DSIO_M?x? opcodes for Vertex shaders to ARB_vertex_program codes */ void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) { @@ -1004,10 +989,11 @@ void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) { SHADER_OPCODE_ARG tmpArg; /* Set constants for the temporary argument */ - tmpArg.shader = arg->shader; - tmpArg.buffer = arg->buffer; - tmpArg.src[0] = arg->src[0]; - + tmpArg.shader = arg->shader; + tmpArg.buffer = arg->buffer; + tmpArg.src[0] = arg->src[0]; + tmpArg.reg_maps = arg->reg_maps; + switch(arg->opcode->opcode) { case D3DSIO_M4x4: nComponents = 4; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d1a38c89902..7cc07b3ea1f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1233,18 +1233,6 @@ void multiply_matrix(D3DMATRIX *dest, D3DMATRIX *src1, D3DMATRIX *src2); /*** class static members ***/ void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface); -/* An enum for the type of constants that are used... addressing causes - * problems with being able to work out what's used and what's not.. so - * maybe we'll have to rely on the server vertex shader const functions? - */ -enum vsConstantsEnum { - VS_CONSTANT_NOT_USED = 0, - VS_CONSTANT_CONSTANT, - VS_CONSTANT_INTEGER, - VS_CONSTANT_BOOLEAN, - VS_CONSTANT_FLOAT -}; - struct SHADER_OPCODE_ARG; typedef void (*shader_fct_t)(); typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*); @@ -1326,6 +1314,9 @@ extern const SHADER_OPCODE* shader_get_opcode( IWineD3DBaseShader *iface, const DWORD code); +/* ARB shader program Prototypes */ +extern void shader_hw_def(SHADER_OPCODE_ARG *arg); + /***************************************************************************** * IDirect3DBaseShader implementation structure */ @@ -1422,9 +1413,7 @@ typedef struct IWineD3DVertexShaderImpl { BOOL namedArrays; /* don't map use named functions */ BOOL declaredArrays; /* mapping requires */ INT arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]; /* lookup table for the maps */ - INT highestConstant; - CHAR constantsUsedBitmap[256]; - /* FIXME: This needs to be populated with some flags of VS_CONSTANT_NOT_USED, VS_CONSTANT_CONSTANT, VS_CONSTANT_INTEGER, VS_CONSTANT_BOOLEAN, VS_CONSTANT_FLOAT, a half byte bitmap will be the best option, but I'll keep it as chards for siplicity */ + /* run time datas... */ VSHADERDATA *data; IWineD3DVertexDeclaration *vertexDeclaration; @@ -1452,8 +1441,6 @@ typedef struct IWineD3DPixelShaderImpl { IUnknown *parent; IWineD3DDeviceImpl *wineD3DDevice; - CHAR constants[WINED3D_PSHADER_MAX_CONSTANTS]; - /* run time data */ PSHADERDATA *data;