diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index f03e23b139e..e64cd0ef07f 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -70,6 +70,7 @@ struct shader_arb_priv { static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info, GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts) { + DWORD shader_version = This->baseShader.reg_maps.shader_version; local_constant* lconst; DWORD i, j; unsigned int ret; @@ -83,8 +84,8 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con } } /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */ - if(target_type == GL_FRAGMENT_PROGRAM_ARB && - WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) { + if (target_type == GL_FRAGMENT_PROGRAM_ARB && WINED3DSHADER_VERSION_MAJOR(shader_version) == 1) + { float lcl_const[4]; for(i = 0; i < max_constants; i++) { if(!dirty_consts[i]) continue; @@ -232,7 +233,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; DWORD i, cur; - char pshader = shader_is_pshader_version(This->baseShader.hex_version); + char pshader = shader_is_pshader_version(reg_maps->shader_version); unsigned max_constantsF = min(This->baseShader.limits.constant_float, (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF))); UINT extra_constants_needed = 0; @@ -360,9 +361,8 @@ static const char * const shift_tab[] = { static void shader_arb_get_write_mask(const SHADER_OPCODE_ARG *arg, const DWORD param, char *write_mask) { - IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) arg->shader; char *ptr = write_mask; - char vshader = shader_is_vshader_version(This->baseShader.hex_version); + char vshader = shader_is_vshader_version(arg->reg_maps->shader_version); if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) { *ptr++ = '.'; @@ -787,7 +787,6 @@ static void pshader_hw_bem(const SHADER_OPCODE_ARG *arg) static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg) { - IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; char dst_wmask[20]; char dst_name[50]; @@ -807,8 +806,8 @@ static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg) pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[2], 2, src_name[2]); /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */ - if (shader->baseShader.hex_version <= WINED3DPS_VERSION(1, 3) && - arg->opcode_token & WINED3DSI_COISSUE) { + if (arg->reg_maps->shader_version <= WINED3DPS_VERSION(1, 3) && arg->opcode_token & WINED3DSI_COISSUE) + { shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]); } else { shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]); @@ -877,7 +876,6 @@ static void pshader_hw_dp2add(const SHADER_OPCODE_ARG *arg) /* Map the opcode 1-to-1 to the GL code */ static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader; CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; DWORD dst = arg->dst; @@ -885,7 +883,7 @@ static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg) char arguments[256]; unsigned int i; - if (shader_is_pshader_version(shader->baseShader.hex_version)) + if (shader_is_pshader_version(arg->reg_maps->shader_version)) { /* Output token related */ char output_rname[256]; @@ -963,8 +961,8 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader; - if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1 - && !shader_is_pshader_version(shader->baseShader.hex_version) + if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1 + && !shader_is_pshader_version(arg->reg_maps->shader_version) && shader_get_regtype(arg->dst) == WINED3DSPR_ADDR) || arg->opcode->opcode == WINED3DSIO_MOVA) { @@ -1008,8 +1006,7 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg) static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg) { - IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; - DWORD hex_version = This->baseShader.hex_version; + DWORD shader_version = arg->reg_maps->shader_version; SHADER_BUFFER* buffer = arg->buffer; char reg_dest[40]; @@ -1018,7 +1015,8 @@ static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg) */ pshader_get_register_name(arg->shader, arg->dst, reg_dest); - if(hex_version >= WINED3DPS_VERSION(2,0)) { + if (shader_version >= WINED3DPS_VERSION(2,0)) + { /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */ shader_addline(buffer, "KIL %s;\n", reg_dest); } else { @@ -1039,7 +1037,7 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg) DWORD dst = arg->dst; const DWORD *src = arg->src; SHADER_BUFFER* buffer = arg->buffer; - DWORD hex_version = This->baseShader.hex_version; + DWORD shader_version = arg->reg_maps->shader_version; BOOL projected = FALSE, bias = FALSE; char reg_dest[40]; @@ -1053,14 +1051,14 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg) /* 1.0-1.3: Use destination register as coordinate source. 1.4+: Use provided coordinate source register. */ - if (hex_version < WINED3DPS_VERSION(1,4)) + if (shader_version < WINED3DPS_VERSION(1,4)) strcpy(reg_coord, reg_dest); else pshader_gen_input_modifier_line(arg->shader, buffer, src[0], 0, reg_coord); /* 1.0-1.4: Use destination register number as texture code. 2.0+: Use provided sampler number as texure code. */ - if (hex_version < WINED3DPS_VERSION(2,0)) + if (shader_version < WINED3DPS_VERSION(2,0)) reg_sampler_code = reg_dest_code; else reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK; @@ -1070,7 +1068,8 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg) * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0] * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode */ - if(hex_version < WINED3DPS_VERSION(1,4)) { + if (shader_version < WINED3DPS_VERSION(1,4)) + { DWORD flags = 0; if(reg_sampler_code < MAX_TEXTURES) { flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]; @@ -1078,7 +1077,9 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg) if (flags & WINED3DTTFF_PROJECTED) { projected = TRUE; } - } else if(hex_version < WINED3DPS_VERSION(2,0)) { + } + else if (shader_version < WINED3DPS_VERSION(2,0)) + { DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK; if (src_mod == WINED3DSPSM_DZ) { projected = TRUE; @@ -1098,14 +1099,13 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg) static void pshader_hw_texcoord(const SHADER_OPCODE_ARG *arg) { - IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; DWORD dst = arg->dst; SHADER_BUFFER* buffer = arg->buffer; - DWORD hex_version = This->baseShader.hex_version; char tmp[20]; shader_arb_get_write_mask(arg, dst, tmp); - if (hex_version != WINED3DPS_VERSION(1,4)) { + if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4)) + { DWORD reg = dst & WINED3DSP_REGNUM_MASK; shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg); } else { @@ -1487,7 +1487,7 @@ static void shader_hw_mnxn(const SHADER_OPCODE_ARG *arg) SHADER_OPCODE_ARG tmpArg; IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader; const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins; - DWORD shader_version = shader->baseShader.hex_version; + DWORD shader_version = arg->reg_maps->shader_version; memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG)); @@ -1787,9 +1787,9 @@ static void shader_arb_cleanup(IWineD3DDevice *iface) { static void shader_arb_destroy(IWineD3DBaseShader *iface) { IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface; const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info; - char pshader = shader_is_pshader_version(baseShader->baseShader.hex_version); - if(pshader) { + if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version)) + { IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface; UINT i; @@ -1868,6 +1868,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; const shader_reg_maps* reg_maps = &This->baseShader.reg_maps; CONST DWORD *function = This->baseShader.function; + DWORD shader_version = reg_maps->shader_version; const char *fragcolor; const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info; const local_constant *lconst; @@ -1890,9 +1891,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF /* We need two variables for fog blending */ shader_addline(buffer, "TEMP TMP_FOG;\n"); - if (This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) { - shader_addline(buffer, "TEMP TMP_COLOR;\n"); - } + if (shader_version >= WINED3DPS_VERSION(2,0)) shader_addline(buffer, "TEMP TMP_COLOR;\n"); /* Base Shader Body */ shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function); @@ -1903,15 +1902,13 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF */ shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n"); - if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) { - fragcolor = "R0"; - } else { - fragcolor = "TMP_COLOR"; - } + fragcolor = (shader_version < WINED3DPS_VERSION(2,0)) ? "R0" : "TMP_COLOR"; + if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) { arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB"); } - if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) { + if (shader_version < WINED3DPS_VERSION(3,0)) + { shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor); shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor); } diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index ad79ee0d1c8..3129554683e 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -206,7 +206,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins; - DWORD shader_version = This->baseShader.hex_version; + DWORD shader_version; unsigned int cur_loop_depth = 0, max_loop_depth = 0; const DWORD* pToken = byte_code; char pshader; @@ -236,8 +236,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m FIXME("First token is not a version token, invalid shader.\n"); return WINED3DERR_INVALIDCALL; } - shader_version = *pToken++; - This->baseShader.hex_version = shader_version; + reg_maps->shader_version = shader_version = *pToken++; pshader = shader_is_pshader_version(shader_version); while (WINED3DVS_END() != *pToken) { @@ -302,7 +301,8 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD)); /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */ - if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && pshader) { + if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 && pshader) + { float *value = (float *) lconst->value; if(value[0] < -1.0) value[0] = -1.0; else if(value[0] > 1.0) value[0] = 1.0; @@ -361,20 +361,20 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m int i, limit; /* Declare 1.X samplers implicitly, based on the destination reg. number */ - if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && - pshader /* Filter different instructions with the same enum values in VS */ && - (WINED3DSIO_TEX == curOpcode->opcode || - WINED3DSIO_TEXBEM == curOpcode->opcode || - WINED3DSIO_TEXBEML == curOpcode->opcode || - WINED3DSIO_TEXDP3TEX == curOpcode->opcode || - WINED3DSIO_TEXM3x2TEX == curOpcode->opcode || - WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode || - WINED3DSIO_TEXM3x3TEX == curOpcode->opcode || - WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode || - WINED3DSIO_TEXREG2AR == curOpcode->opcode || - WINED3DSIO_TEXREG2GB == curOpcode->opcode || - WINED3DSIO_TEXREG2RGB == curOpcode->opcode)) { - + if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 + && pshader /* Filter different instructions with the same enum values in VS */ + && (WINED3DSIO_TEX == curOpcode->opcode + || WINED3DSIO_TEXBEM == curOpcode->opcode + || WINED3DSIO_TEXBEML == curOpcode->opcode + || WINED3DSIO_TEXDP3TEX == curOpcode->opcode + || WINED3DSIO_TEXM3x2TEX == curOpcode->opcode + || WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode + || WINED3DSIO_TEXM3x3TEX == curOpcode->opcode + || WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode + || WINED3DSIO_TEXREG2AR == curOpcode->opcode + || WINED3DSIO_TEXREG2GB == curOpcode->opcode + || WINED3DSIO_TEXREG2RGB == curOpcode->opcode)) + { /* Fake sampler usage, only set reserved bit and ttype */ DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK; @@ -476,8 +476,9 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT * isn't used in them, but future register types might cause issues */ - else if(WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ && - !pshader && WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) < 3) { + else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ + && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3) + { reg_maps->texcoord_mask[reg] |= shader_get_writemask(param); } } @@ -832,7 +833,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */ const SHADER_OPCODE *opcode_table = This->baseShader.shader_ins; const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table; - DWORD shader_version = This->baseShader.hex_version; + DWORD shader_version = reg_maps->shader_version; const DWORD *pToken = pFunction; const SHADER_OPCODE *curOpcode = NULL; SHADER_HANDLER hw_fct = NULL; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 3f54170033e..ee0aa6ca148 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -220,8 +220,9 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const Wine } /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */ - if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && - shader_is_pshader_version(This->baseShader.hex_version)) { + if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.reg_maps.shader_version) == 1 + && shader_is_pshader_version(This->baseShader.reg_maps.shader_version)) + { float lcl_const[4]; LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) { @@ -336,7 +337,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine GLhandleARB tmp_loc; unsigned int i; char tmp_name[8]; - char is_pshader = shader_is_pshader_version(This->baseShader.hex_version); + char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version); const char* prefix = is_pshader? "PB":"VB"; struct list* ptr; @@ -503,11 +504,12 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; + DWORD shader_version = reg_maps->shader_version; unsigned int i, extra_constants_needed = 0; const local_constant *lconst; /* There are some minor differences between pixel and vertex shaders */ - char pshader = shader_is_pshader_version(This->baseShader.hex_version); + char pshader = shader_is_pshader_version(shader_version); char prefix = pshader ? 'P' : 'V'; /* Prototype the subroutines */ @@ -541,7 +543,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s * out. The nvidia driver only does that if the parameter is inout instead of out, hence the * inout. */ - if(This->baseShader.hex_version >= WINED3DVS_VERSION(3, 0)) { + if (shader_version >= WINED3DVS_VERSION(3, 0)) + { shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT); } else { shader_addline(buffer, "void order_ps_input();\n"); @@ -642,7 +645,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the * helper function shader that is linked in at link time */ - if(pshader && This->baseShader.hex_version >= WINED3DPS_VERSION(3, 0)) { + if (pshader && shader_version >= WINED3DPS_VERSION(3, 0)) + { if(use_vs(device)) { shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4); } else { @@ -812,8 +816,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info; - - char pshader = shader_is_pshader_version(This->baseShader.hex_version); + DWORD shader_version = This->baseShader.reg_maps.shader_version; + char pshader = shader_is_pshader_version(shader_version); char tmpStr[150]; *is_color = FALSE; @@ -825,7 +829,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to case WINED3DSPR_INPUT: if (pshader) { /* Pixel shaders >= 3.0 */ - if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) { + if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) + { DWORD in_count = GL_LIMITS(glsl_varyings) / 4; if (param & WINED3DSHADER_ADDRMODE_RELATIVE) { @@ -885,7 +890,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to /* Relative addressing on shaders 2.0+ have a relative address token, * prior to that, it was hard-coded as "A0.x" because there's only 1 register */ - if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2) { + if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2) + { glsl_src_param_t rel_param; shader_glsl_add_src_param(arg, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param); if(reg) { @@ -964,10 +970,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to break; case WINED3DSPR_TEXCRDOUT: /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */ - if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) - sprintf(tmpStr, "OUT[%u]", reg); - else - sprintf(tmpStr, "gl_TexCoord[%u]", reg); + if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(tmpStr, "OUT[%u]", reg); + else sprintf(tmpStr, "gl_TexCoord[%u]", reg); break; case WINED3DSPR_MISCTYPE: if (reg == 0) { @@ -1316,7 +1320,6 @@ static void shader_glsl_arith(const SHADER_OPCODE_ARG *arg) /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */ static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg) { - IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src0_param; DWORD write_mask; @@ -1326,9 +1329,10 @@ static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg) /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later * shader versions WINED3DSIO_MOVA is used for this. */ - if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1 && - !shader_is_pshader_version(shader->baseShader.hex_version) && - shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)) { + if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1 + && !shader_is_pshader_version(arg->reg_maps->shader_version) + && shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)) + { /* This is a simple floor() */ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask); if (mask_size > 1) { @@ -1496,12 +1500,12 @@ static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg) */ static void shader_glsl_expp(const SHADER_OPCODE_ARG *arg) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader; glsl_src_param_t src_param; shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param); - if (shader->baseShader.hex_version < WINED3DPS_VERSION(2,0)) { + if (arg->reg_maps->shader_version < WINED3DPS_VERSION(2,0)) + { char dst_mask[6]; shader_addline(arg->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str); @@ -1692,14 +1696,14 @@ static void shader_glsl_cmp(const SHADER_OPCODE_ARG *arg) * the compare is done per component of src0. */ static void shader_glsl_cnd(const SHADER_OPCODE_ARG *arg) { - IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; DWORD write_mask, cmp_channel = 0; unsigned int i, j; - if (shader->baseShader.hex_version < WINED3DPS_VERSION(1, 4)) { + if (arg->reg_maps->shader_version < WINED3DPS_VERSION(1, 4)) + { write_mask = shader_glsl_append_dst(arg->buffer, arg); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param); shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param); @@ -1758,7 +1762,7 @@ static void shader_glsl_mnxn(const SHADER_OPCODE_ARG *arg) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader; const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins; - DWORD shader_version = shader->baseShader.hex_version; + DWORD shader_version = arg->reg_maps->shader_version; int i; int nComponents = 0; SHADER_OPCODE_ARG tmpArg; @@ -2094,7 +2098,7 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; - DWORD hex_version = This->baseShader.hex_version; + DWORD shader_version = arg->reg_maps->shader_version; char dst_swizzle[6]; glsl_sample_function_t sample_function; DWORD sampler_type; @@ -2107,14 +2111,12 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) /* 1.0-1.4: Use destination register as sampler source. * 2.0+: Use provided sampler source. */ - if (hex_version < WINED3DPS_VERSION(2,0)) { - sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; - } else { - sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK; - } + if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; + else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK; sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; - if (hex_version < WINED3DPS_VERSION(1,4)) { + if (shader_version < WINED3DPS_VERSION(1,4)) + { DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ @@ -2130,7 +2132,9 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) } else { projected = FALSE; } - } else if (hex_version < WINED3DPS_VERSION(2,0)) { + } + else if (shader_version < WINED3DPS_VERSION(2,0)) + { DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK; if (src_mod == WINED3DSPSM_DZ) { @@ -2160,15 +2164,13 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) shader_glsl_get_sample_function(sampler_type, projected, texrect, &sample_function); mask |= sample_function.coord_mask; - if (hex_version < WINED3DPS_VERSION(2,0)) { - shader_glsl_get_write_mask(arg->dst, dst_swizzle); - } else { - shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle); - } + if (shader_version < WINED3DPS_VERSION(2,0)) shader_glsl_get_write_mask(arg->dst, dst_swizzle); + else shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle); /* 1.0-1.3: Use destination register as coordinate source. 1.4+: Use provided coordinate source register. */ - if (hex_version < WINED3DPS_VERSION(1,4)) { + if (shader_version < WINED3DPS_VERSION(1,4)) + { char coord_mask[6]; shader_glsl_get_write_mask(mask, coord_mask); shader_addline(arg->buffer, "%s(Psampler%u, T%u%s)%s);\n", @@ -2214,7 +2216,8 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg) shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param); - if (shader_is_pshader_version(This->baseShader.hex_version)) { + if (shader_is_pshader_version(arg->reg_maps->shader_version)) + { /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders. * However, they seem to work just fine in fragment shaders as well. */ WARN("Using %sLod in fragment shader.\n", sample_function.name); @@ -2229,17 +2232,15 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg) static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg) { /* FIXME: Make this work for more than just 2D textures */ - - IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; - DWORD hex_version = This->baseShader.hex_version; DWORD write_mask; char dst_mask[6]; write_mask = shader_glsl_append_dst(arg->buffer, arg); shader_glsl_get_write_mask(write_mask, dst_mask); - if (hex_version != WINED3DPS_VERSION(1,4)) { + if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4)) + { DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask); } else { @@ -2663,13 +2664,12 @@ static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg) * If any of the first 3 components are < 0, discard this pixel */ static void pshader_glsl_texkill(const SHADER_OPCODE_ARG *arg) { - IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; - DWORD hex_version = This->baseShader.hex_version; glsl_dst_param_t dst_param; /* The argument is a destination parameter, and no writemasks are allowed */ shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param); - if((hex_version >= WINED3DPS_VERSION(2,0))) { + if ((arg->reg_maps->shader_version >= WINED3DPS_VERSION(2,0))) + { /* 2.0 shaders compare all 4 components in texkill */ shader_addline(arg->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name); } else { @@ -2957,8 +2957,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader; IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader; IWineD3DDeviceImpl *device; - DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.hex_version); - DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.hex_version) : 0; + DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.reg_maps.shader_version); + DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0; unsigned int i; SHADER_BUFFER buffer; DWORD usage_token; @@ -3270,8 +3270,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection")); checkGLcall("Find glsl program uniform locations"); - if (pshader && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.hex_version) >= 3 - && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4) { + if (pshader + && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version) >= 3 + && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4) + { TRACE("Shader %d needs vertex color clamping disabled\n", programId); entry->vertex_color_clamp = GL_FALSE; } else { @@ -3462,7 +3464,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { /* Note: Do not use QueryInterface here to find out which shader type this is because this code * can be called from IWineD3DBaseShader::Release */ - char pshader = shader_is_pshader_version(This->baseShader.hex_version); + char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version); if(pshader) { ps = (IWineD3DPixelShaderImpl *) This; @@ -3596,8 +3598,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION); /* Pack 3.0 inputs */ - if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) { - + if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0)) + { if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) { pshader_glsl_input_pack(buffer, This->semantics_in, iface, pretransformed); } else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device)) { @@ -3609,7 +3611,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function); /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */ - if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) { + if (reg_maps->shader_version < WINED3DPS_VERSION(2,0)) + { /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */ if(GL_SUPPORT(ARB_DRAW_BUFFERS)) shader_addline(buffer, "gl_FragData[0] = R0;\n"); @@ -3638,7 +3641,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but * -1/(e-s) and e/(e-s) respectively. */ - if(This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) { + if (reg_maps->shader_version < WINED3DPS_VERSION(3,0)) + { shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n"); shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor); } @@ -3672,11 +3676,8 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function); /* Unpack 3.0 outputs */ - if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) { - shader_addline(buffer, "order_ps_input(OUT);\n"); - } else { - shader_addline(buffer, "order_ps_input();\n"); - } + if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n"); + else shader_addline(buffer, "order_ps_input();\n"); /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */ if (!reg_maps->fog) diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 5857ce7f496..f3d4386cfc5 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -226,7 +226,8 @@ static void pshader_set_limits( This->baseShader.limits.address = 0; This->baseShader.limits.packed_output = 0; - switch (This->baseShader.hex_version) { + switch (This->baseShader.reg_maps.shader_version) + { case WINED3DPS_VERSION(1,0): case WINED3DPS_VERSION(1,1): case WINED3DPS_VERSION(1,2): @@ -293,8 +294,8 @@ static void pshader_set_limits( This->baseShader.limits.sampler = 16; This->baseShader.limits.packed_input = 0; This->baseShader.limits.label = 0; - FIXME("Unrecognized pixel shader version %#x\n", - This->baseShader.hex_version); + FIXME("Unrecognized pixel shader version %#x\n", + This->baseShader.reg_maps.shader_version); } } @@ -395,9 +396,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i return WINED3D_OK; } -static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures, - DWORD shader_version) +static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) { + DWORD shader_version = reg_maps->shader_version; DWORD *samplers = reg_maps->samplers; unsigned int i; @@ -448,7 +449,7 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps TRACE("(%p) : function %p\n", This, function); pixelshader_update_samplers(&This->baseShader.reg_maps, - ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures, This->baseShader.hex_version); + ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures); /* Reset fields tracking stateblock values being hardcoded in the shader */ This->baseShader.num_sampled_samplers = 0; @@ -493,7 +494,8 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp } args->color_fixup[sampler] = tex->baseTexture.shader_color_fixup; } - if(shader->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) { + if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0)) + { if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) { args->vp_mode = pretransformed; } else if(use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) { diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d55a08d4f3e..ccaf6f57553 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -901,8 +901,9 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE]; + IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *)stateblock->pixelShader; BOOL is_ps3 = use_ps(stateblock->wineD3DDevice) - && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0); + && ps_impl->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0); float fogstart, fogend; union { @@ -914,8 +915,9 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo /* No fog? Disable it, and we're done :-) */ glDisable(GL_FOG); checkGLcall("glDisable GL_FOG"); - if( use_ps(stateblock->wineD3DDevice) - && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) { + if (use_ps(stateblock->wineD3DDevice) + && ps_impl->baseShader.reg_maps.shader_version < WINED3DPS_VERSION(3,0)) + { /* disable fog in the pixel shader * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but * -1/(e-s) and e/(e-s) respectively. diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index ea8781f15cb..ef55f67807a 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -120,7 +120,8 @@ static void vshader_set_limits( /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */ This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF); - switch (This->baseShader.hex_version) { + switch (This->baseShader.reg_maps.shader_version) + { case WINED3DVS_VERSION(1,0): case WINED3DVS_VERSION(1,1): This->baseShader.limits.temporary = 12; @@ -161,7 +162,7 @@ static void vshader_set_limits( This->baseShader.limits.sampler = 0; This->baseShader.limits.label = 16; FIXME("Unrecognized vertex shader version %#x\n", - This->baseShader.hex_version); + This->baseShader.reg_maps.shader_version); } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0b444bb2a9e..a6605818d44 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2067,7 +2067,7 @@ typedef struct local_constant { } local_constant; typedef struct shader_reg_maps { - + DWORD shader_version; char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */ char temporary[MAX_REG_TEMP]; /* pixel, vertex */ char address[MAX_REG_ADDR]; /* vertex */ @@ -2185,7 +2185,6 @@ extern void shader_glsl_add_instruction_modifiers(const SHADER_OPCODE_ARG *arg); typedef struct IWineD3DBaseShaderClass { LONG ref; - DWORD hex_version; SHADER_LIMITS limits; SHADER_PARSE_STATE parse_state; CONST SHADER_OPCODE *shader_ins;