[PATCH 2/5] wined3d: Fix fragment shaders sampling directly into oC[n] in the ARB backend.
Matteo Bruni
mbruni at codeweavers.com
Tue May 19 16:32:32 CDT 2015
---
dlls/wined3d/arb_program_shader.c | 118 ++++++++++++++++++++++++++------------
1 file changed, 81 insertions(+), 37 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index a45d25f..1e8784e 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -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,
- DWORD dst_mask, const char *one, const char *two, struct color_fixup_desc fixup)
+struct color_fixup_masks
{
- 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))
{
enum complex_fixup complex_fixup = get_complex_fixup(fixup);
FIXME("Complex fixup (%#x) not supported\n", complex_fixup);
- return;
+ return masks;
}
- mask = 0;
- if (fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0;
- if (fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1;
- if (fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2;
- if (fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3;
- mask &= dst_mask;
+ if (fixup.x_source != CHANNEL_SOURCE_X)
+ masks.source |= WINED3DSP_WRITEMASK_0;
+ if (fixup.y_source != CHANNEL_SOURCE_Y)
+ masks.source |= WINED3DSP_WRITEMASK_1;
+ if (fixup.z_source != CHANNEL_SOURCE_Z)
+ 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.z_source), shader_arb_get_fixup_swizzle(fixup.w_source));
}
+ else if (masks.sign)
+ {
+ sign_fixup_src = src;
+ }
- mask = 0;
- 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)
+ if (masks.sign)
{
char reg_mask[6];
char *ptr = reg_mask;
- if (mask != WINED3DSP_WRITEMASK_ALL)
+ if (masks.sign != WINED3DSP_WRITEMASK_ALL)
{
*ptr++ = '.';
- if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
- if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
- if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
- if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
+ if (masks.sign & WINED3DSP_WRITEMASK_0)
+ *ptr++ = 'x';
+ if (masks.sign & WINED3DSP_WRITEMASK_1)
+ *ptr++ = 'y';
+ if (masks.sign & WINED3DSP_WRITEMASK_2)
+ *ptr++ = 'z';
+ if (masks.sign & WINED3DSP_WRITEMASK_3)
+ *ptr++ = 'w';
}
*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
const struct wined3d_shader *shader;
const struct wined3d_device *device;
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 */
if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
@@ -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];
}
+ 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_PROJ) FIXME("Projected 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,
- dsx, dsy,sampler_idx, tex_type);
+ shader_addline(buffer, "TXD%s %s, %s, %s, %s, texture[%u], %s;\n", mod, tex_dst, coord_reg,
+ dsx, dsy, sampler_idx, tex_type);
}
else if(flags & TEX_LOD)
{
if(flags & TEX_PROJ) FIXME("Projected 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);
}
else if (flags & TEX_BIAS)
@@ -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 */
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 */
- 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)
{
- 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
{
@@ -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,
(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
- 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)
{
- 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_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
BOOL op_equal;
const char *final_combiner_src = "ret";
BOOL custom_linear_fog = FALSE;
+ struct color_fixup_masks masks;
if (!string_buffer_init(&buffer))
{
@@ -6426,8 +6469,9 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con
}
sprintf(colorcor_dst, "tex%u", stage);
- gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y",
- settings->op[stage].color_fixup);
+ masks = calc_color_correction(settings->op[stage].color_fixup, WINED3DSP_WRITEMASK_ALL);
+ gen_color_correction(&buffer, colorcor_dst, colorcor_dst, "const.x", "const.y",
+ settings->op[stage].color_fixup, masks);
}
if (settings->color_key_enabled)
--
2.3.6
More information about the wine-patches
mailing list