diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index a7a79c190f4..4be1a1fc76f 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -10,6 +10,7 @@ * Copyright 2006 Jason Green * Copyright 2006 Henri Verbeet * Copyright 2007-2008 Stefan Dösinger for CodeWeavers + * Copyright 2009 Henri Verbeet for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -577,7 +578,7 @@ static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *in strcat(str, " "); shader_arb_get_register_name(ins->ctx->shader, wined3d_dst->register_type, - wined3d_dst->register_idx, wined3d_dst->has_rel_addr, register_name, &is_color); + wined3d_dst->register_idx, !!wined3d_dst->rel_addr, register_name, &is_color); strcat(str, register_name); shader_arb_get_write_mask(ins, wined3d_dst, write_mask); @@ -814,7 +815,7 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) } shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); strcat(dst_name, dst_wmask); @@ -849,7 +850,7 @@ static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins) /* Handle output register */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); /* Generate input register names (with modifiers) */ @@ -885,7 +886,7 @@ static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins) /* Handle output register */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); /* Generate input register names (with modifiers) */ @@ -914,7 +915,7 @@ static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins) BOOL is_color; shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->ctx->shader, buffer, ins->src[0].token, 0, src_name[0]); @@ -1016,7 +1017,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) /* Handle output register */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, output_rname, &is_color); + dst->register_idx, !!dst->rel_addr, output_rname, &is_color); strcpy(operands[0], output_rname); shader_arb_get_write_mask(ins, dst, output_wmask); strcat(operands[0], output_wmask); @@ -1108,7 +1109,7 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins) * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit) */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, reg_dest, &is_color); + dst->register_idx, !!dst->rel_addr, reg_dest, &is_color); if (shader_version >= WINED3DPS_VERSION(2,0)) { @@ -1140,7 +1141,7 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) /* All versions have a destination register */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, reg_dest, &is_color); + dst->register_idx, !!dst->rel_addr, reg_dest, &is_color); /* 1.0-1.3: Use destination register as coordinate source. 1.4+: Use provided coordinate source register. */ @@ -1269,7 +1270,7 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) reg_dest_code = dst->register_idx; /* Can directly use the name because texbem is only valid for <= 1.3 shaders */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, reg_coord, &is_color); + dst->register_idx, !!dst->rel_addr, reg_coord, &is_color); for(i = 0; i < This->numbumpenvmatconsts; i++) { if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED @@ -1478,7 +1479,7 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) * here */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); /* According to the msdn, the source register(must be r5) is unusable after * the texdepth instruction, so we're free to modify it @@ -1526,7 +1527,7 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins) /* Handle output register */ shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_str, &is_color); + dst->register_idx, !!dst->rel_addr, dst_str, &is_color); shader_arb_get_write_mask(ins, dst, dst_mask); pshader_gen_input_modifier_line(ins->ctx->shader, buffer, ins->src[0].token, 0, src0); @@ -1547,7 +1548,7 @@ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins) BOOL is_color; shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_str, &is_color); + dst->register_idx, !!dst->rel_addr, dst_str, &is_color); shader_arb_get_write_mask(ins, dst, dst_mask); pshader_gen_input_modifier_line(ins->ctx->shader, buffer, ins->src[0].token, 0, src0); @@ -1681,7 +1682,7 @@ static void shader_hw_nrm(const struct wined3d_shader_instruction *ins) BOOL is_color; shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->ctx->shader, buffer, ins->src[0].token, 0, src_name); @@ -1711,7 +1712,7 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins) BOOL is_color; shader_arb_get_register_name(ins->ctx->shader, dst->register_type, - dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + dst->register_idx, !!dst->rel_addr, dst_name, &is_color); shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->ctx->shader, buffer, ins->src[0].token, 0, src_name); diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 154354bf5d8..0d41fdc7a55 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -227,7 +227,8 @@ static void shader_delete_constant_list(struct list* clist) { list_init(clist); } -static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst) +static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, + struct wined3d_shader_dst_param *dst) { dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); @@ -235,8 +236,7 @@ static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d dst->write_mask = param & WINED3DSP_WRITEMASK_ALL; dst->modifiers = param & WINED3DSP_DSTMOD_MASK; dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - dst->has_rel_addr = param & WINED3DSHADER_ADDRMODE_RELATIVE; - dst->addr_token = addr_param; + dst->rel_addr = rel_addr; } static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, @@ -327,7 +327,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; semantics_in[regnum].usage_idx = (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_parse_dst_param(param, 0, &semantics_in[regnum].reg); + shader_parse_dst_param(param, NULL, &semantics_in[regnum].reg); /* Vshader: mark 3.0 output registers used, save token */ } else if (WINED3DSPR_OUTPUT == regtype) { @@ -335,7 +335,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; semantics_out[regnum].usage_idx = (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_parse_dst_param(param, 0, &semantics_out[regnum].reg); + shader_parse_dst_param(param, NULL, &semantics_out[regnum].reg); if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT)) reg_maps->fog = 1; @@ -817,6 +817,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, DWORD shader_version = reg_maps->shader_version; struct wined3d_shader_src_param src_rel_addr[4]; struct wined3d_shader_src_param src_param[4]; + struct wined3d_shader_src_param dst_rel_addr; struct wined3d_shader_dst_param dst_param; struct wined3d_shader_instruction ins; struct wined3d_shader_context ctx; @@ -898,9 +899,18 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, ins.dst_count = curOpcode->dst_token ? 1 : 0; if (ins.dst_count) { - DWORD param, addr_param = 0; + DWORD param, addr_param; pToken += shader_get_param(pToken, shader_version, ¶m, &addr_param); - shader_parse_dst_param(param, addr_param, &dst_param); + + if (param & WINED3DSHADER_ADDRMODE_RELATIVE) + { + shader_parse_src_param(addr_param, NULL, &dst_rel_addr); + shader_parse_dst_param(param, &dst_rel_addr, &dst_param); + } + else + { + shader_parse_dst_param(param, NULL, &dst_param); + } } /* Predication token */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 8c4548ade64..429695b33a3 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1295,7 +1295,8 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction * glsl_dst->reg_name[0] = '\0'; shader_glsl_get_register_name(wined3d_dst->register_type, wined3d_dst->register_idx, - wined3d_dst->has_rel_addr, wined3d_dst->addr_token, glsl_dst->reg_name, &is_color, ins); + !!wined3d_dst->rel_addr, wined3d_dst->rel_addr ? wined3d_dst->rel_addr->token : 0, + glsl_dst->reg_name, &is_color, ins); return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str); } diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index fdd8cd8b35e..fab0dcaa8f7 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -181,8 +181,7 @@ static void vshader_set_input( This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL; This->semantics_in[regnum].reg.modifiers = 0; This->semantics_in[regnum].reg.shift = 0; - This->semantics_in[regnum].reg.has_rel_addr = FALSE; - This->semantics_in[regnum].reg.addr_token = 0; + This->semantics_in[regnum].reg.rel_addr = NULL; } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9f182193fe7..09f7821d5a7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -458,8 +458,7 @@ struct wined3d_shader_dst_param DWORD write_mask; DWORD modifiers; DWORD shift; - BOOL has_rel_addr; - DWORD addr_token; + const struct wined3d_shader_src_param *rel_addr; }; struct wined3d_shader_src_param