Commit 5b911ed4 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

wined3d: Fix fragment shaders sampling directly into oC[n] in the ARB backend.

parent 409cda0a
...@@ -1271,55 +1271,86 @@ static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channe ...@@ -1271,55 +1271,86 @@ static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channe
} }
} }
static void gen_color_correction(struct wined3d_string_buffer *buffer, const char *reg, struct color_fixup_masks
DWORD dst_mask, const char *one, const char *two, struct color_fixup_desc fixup)
{ {
DWORD mask; DWORD source;
DWORD sign;
};
static struct color_fixup_masks calc_color_correction(struct color_fixup_desc fixup, DWORD dst_mask)
{
struct color_fixup_masks masks = {0, 0};
if (is_complex_fixup(fixup)) if (is_complex_fixup(fixup))
{ {
enum complex_fixup complex_fixup = get_complex_fixup(fixup); enum complex_fixup complex_fixup = get_complex_fixup(fixup);
FIXME("Complex fixup (%#x) not supported\n", complex_fixup); FIXME("Complex fixup (%#x) not supported\n", complex_fixup);
return; return masks;
} }
mask = 0; if (fixup.x_source != CHANNEL_SOURCE_X)
if (fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0; masks.source |= WINED3DSP_WRITEMASK_0;
if (fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1; if (fixup.y_source != CHANNEL_SOURCE_Y)
if (fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2; masks.source |= WINED3DSP_WRITEMASK_1;
if (fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3; if (fixup.z_source != CHANNEL_SOURCE_Z)
mask &= dst_mask; masks.source |= WINED3DSP_WRITEMASK_2;
if (fixup.w_source != CHANNEL_SOURCE_W)
masks.source |= WINED3DSP_WRITEMASK_3;
masks.source &= dst_mask;
if (fixup.x_sign_fixup)
masks.sign |= WINED3DSP_WRITEMASK_0;
if (fixup.y_sign_fixup)
masks.sign |= WINED3DSP_WRITEMASK_1;
if (fixup.z_sign_fixup)
masks.sign |= WINED3DSP_WRITEMASK_2;
if (fixup.w_sign_fixup)
masks.sign |= WINED3DSP_WRITEMASK_3;
masks.sign &= dst_mask;
return masks;
}
static void gen_color_correction(struct wined3d_string_buffer *buffer, const char *dst,
const char *src, const char *one, const char *two,
struct color_fixup_desc fixup, struct color_fixup_masks masks)
{
const char *sign_fixup_src = dst;
if (mask) if (masks.source)
{ {
shader_addline(buffer, "SWZ %s, %s, %s, %s, %s, %s;\n", reg, reg, if (masks.sign)
sign_fixup_src = "TA";
shader_addline(buffer, "SWZ %s, %s, %s, %s, %s, %s;\n", sign_fixup_src, src,
shader_arb_get_fixup_swizzle(fixup.x_source), shader_arb_get_fixup_swizzle(fixup.y_source), shader_arb_get_fixup_swizzle(fixup.x_source), shader_arb_get_fixup_swizzle(fixup.y_source),
shader_arb_get_fixup_swizzle(fixup.z_source), shader_arb_get_fixup_swizzle(fixup.w_source)); shader_arb_get_fixup_swizzle(fixup.z_source), shader_arb_get_fixup_swizzle(fixup.w_source));
} }
else if (masks.sign)
{
sign_fixup_src = src;
}
mask = 0; if (masks.sign)
if (fixup.x_sign_fixup) mask |= WINED3DSP_WRITEMASK_0;
if (fixup.y_sign_fixup) mask |= WINED3DSP_WRITEMASK_1;
if (fixup.z_sign_fixup) mask |= WINED3DSP_WRITEMASK_2;
if (fixup.w_sign_fixup) mask |= WINED3DSP_WRITEMASK_3;
mask &= dst_mask;
if (mask)
{ {
char reg_mask[6]; char reg_mask[6];
char *ptr = reg_mask; char *ptr = reg_mask;
if (mask != WINED3DSP_WRITEMASK_ALL) if (masks.sign != WINED3DSP_WRITEMASK_ALL)
{ {
*ptr++ = '.'; *ptr++ = '.';
if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x'; if (masks.sign & WINED3DSP_WRITEMASK_0)
if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y'; *ptr++ = 'x';
if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z'; if (masks.sign & WINED3DSP_WRITEMASK_1)
if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w'; *ptr++ = 'y';
if (masks.sign & WINED3DSP_WRITEMASK_2)
*ptr++ = 'z';
if (masks.sign & WINED3DSP_WRITEMASK_3)
*ptr++ = 'w';
} }
*ptr = '\0'; *ptr = '\0';
shader_addline(buffer, "MAD %s%s, %s, %s, -%s;\n", reg, reg_mask, reg, two, one); shader_addline(buffer, "MAD %s%s, %s, %s, -%s;\n", dst, reg_mask, sign_fixup_src, two, one);
} }
} }
...@@ -1378,6 +1409,8 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD ...@@ -1378,6 +1409,8 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
const struct wined3d_shader *shader; const struct wined3d_shader *shader;
const struct wined3d_device *device; const struct wined3d_device *device;
const struct wined3d_gl_info *gl_info; const struct wined3d_gl_info *gl_info;
const char *tex_dst = dst_str;
struct color_fixup_masks masks;
/* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */ /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS; if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
...@@ -1433,18 +1466,27 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD ...@@ -1433,18 +1466,27 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS]; sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS];
} }
if (pshader)
{
masks = calc_color_correction(priv->cur_ps_args->super.color_fixup[sampler_idx],
ins->dst[0].write_mask);
if (masks.source || masks.sign)
tex_dst = "TA";
}
if (flags & TEX_DERIV) if (flags & TEX_DERIV)
{ {
if(flags & TEX_PROJ) FIXME("Projected texture sampling with custom derivatives\n"); if(flags & TEX_PROJ) FIXME("Projected texture sampling with custom derivatives\n");
if(flags & TEX_BIAS) FIXME("Biased texture sampling with custom derivatives\n"); if(flags & TEX_BIAS) FIXME("Biased texture sampling with custom derivatives\n");
shader_addline(buffer, "TXD%s %s, %s, %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, shader_addline(buffer, "TXD%s %s, %s, %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg,
dsx, dsy,sampler_idx, tex_type); dsx, dsy, sampler_idx, tex_type);
} }
else if(flags & TEX_LOD) else if(flags & TEX_LOD)
{ {
if(flags & TEX_PROJ) FIXME("Projected texture sampling with explicit lod\n"); if(flags & TEX_PROJ) FIXME("Projected texture sampling with explicit lod\n");
if(flags & TEX_BIAS) FIXME("Biased texture sampling with explicit lod\n"); if(flags & TEX_BIAS) FIXME("Biased texture sampling with explicit lod\n");
shader_addline(buffer, "TXL%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, shader_addline(buffer, "TXL%s %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg,
sampler_idx, tex_type); sampler_idx, tex_type);
} }
else if (flags & TEX_BIAS) else if (flags & TEX_BIAS)
...@@ -1452,11 +1494,11 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD ...@@ -1452,11 +1494,11 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
/* Shouldn't be possible, but let's check for it */ /* Shouldn't be possible, but let's check for it */
if(flags & TEX_PROJ) FIXME("Biased and Projected texture sampling\n"); if(flags & TEX_PROJ) FIXME("Biased and Projected texture sampling\n");
/* TXB takes the 4th component of the source vector automatically, as d3d. Nothing more to do */ /* TXB takes the 4th component of the source vector automatically, as d3d. Nothing more to do */
shader_addline(buffer, "TXB%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type); shader_addline(buffer, "TXB%s %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg, sampler_idx, tex_type);
} }
else if (flags & TEX_PROJ) else if (flags & TEX_PROJ)
{ {
shader_addline(buffer, "TXP%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type); shader_addline(buffer, "TXP%s %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg, sampler_idx, tex_type);
} }
else else
{ {
...@@ -1466,18 +1508,18 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD ...@@ -1466,18 +1508,18 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
shader_addline(buffer, "MUL TA, np2fixup[%u].%s, %s;\n", idx >> 1, shader_addline(buffer, "MUL TA, np2fixup[%u].%s, %s;\n", idx >> 1,
(idx % 2) ? "zwxy" : "xyzw", coord_reg); (idx % 2) ? "zwxy" : "xyzw", coord_reg);
shader_addline(buffer, "TEX%s %s, TA, texture[%u], %s;\n", mod, dst_str, sampler_idx, tex_type); shader_addline(buffer, "TEX%s %s, TA, texture[%u], %s;\n", mod, tex_dst, sampler_idx, tex_type);
} }
else else
shader_addline(buffer, "TEX%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type); shader_addline(buffer, "TEX%s %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg, sampler_idx, tex_type);
} }
if (pshader) if (pshader)
{ {
gen_color_correction(buffer, dst_str, ins->dst[0].write_mask, gen_color_correction(buffer, dst_str, tex_dst,
arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE), arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE),
arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO), arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO),
priv->cur_ps_args->super.color_fixup[sampler_idx]); priv->cur_ps_args->super.color_fixup[sampler_idx], masks);
} }
} }
...@@ -6238,6 +6280,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con ...@@ -6238,6 +6280,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
BOOL op_equal; BOOL op_equal;
const char *final_combiner_src = "ret"; const char *final_combiner_src = "ret";
BOOL custom_linear_fog = FALSE; BOOL custom_linear_fog = FALSE;
struct color_fixup_masks masks;
if (!string_buffer_init(&buffer)) if (!string_buffer_init(&buffer))
{ {
...@@ -6426,8 +6469,9 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con ...@@ -6426,8 +6469,9 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
} }
sprintf(colorcor_dst, "tex%u", stage); sprintf(colorcor_dst, "tex%u", stage);
gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y", masks = calc_color_correction(settings->op[stage].color_fixup, WINED3DSP_WRITEMASK_ALL);
settings->op[stage].color_fixup); gen_color_correction(&buffer, colorcor_dst, colorcor_dst, "const.x", "const.y",
settings->op[stage].color_fixup, masks);
} }
if (settings->color_key_enabled) if (settings->color_key_enabled)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment