[PATCH 2/5] wined3d: Improve color fixups in atifs shaders.

Stefan Dösinger stefan at codeweavers.com
Mon Mar 23 12:59:07 CDT 2015


The abilities of this hardware is too limited to support generic sign /
swizzle fixups. A generic handler would consume 4 of the 8 available
color instruction slots and 2 alpha instruction slots.

The bump mapping handler code has its own way of handling the color
fixups. It merges the fixup into the perturbation calculation without
requiring extra shader instructions. In theory this is possible for the
majority of d3d texture ops as well, but I don't think this is worth the
effort. I expect that this code will only be used for the ddraw signed
format test in practise.
---
 dlls/wined3d/ati_fragment_shader.c | 90 +++++++++++++++++++++++++++++++-------
 1 file changed, 75 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c
index 1570a04..8dfb568 100644
--- a/dlls/wined3d/ati_fragment_shader.c
+++ b/dlls/wined3d/ati_fragment_shader.c
@@ -376,6 +376,69 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
     }
 }
 
+static const struct color_fixup_desc color_fixup_rg =
+{
+    1, CHANNEL_SOURCE_X,
+    1, CHANNEL_SOURCE_Y,
+    0, CHANNEL_SOURCE_ONE,
+    0, CHANNEL_SOURCE_ONE
+};
+static const struct color_fixup_desc color_fixup_rgl =
+{
+    1, CHANNEL_SOURCE_X,
+    1, CHANNEL_SOURCE_Y,
+    0, CHANNEL_SOURCE_Z,
+    0, CHANNEL_SOURCE_W
+};
+static const struct color_fixup_desc color_fixup_rgba =
+{
+    1, CHANNEL_SOURCE_X,
+    1, CHANNEL_SOURCE_Y,
+    1, CHANNEL_SOURCE_Z,
+    1, CHANNEL_SOURCE_W
+};
+
+static BOOL op_reads_texture(const struct texture_stage_op *op)
+{
+    return (op->carg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || (op->carg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || (op->carg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || (op->aarg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || (op->aarg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || (op->aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+            || op->cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA;
+}
+
+static void atifs_color_fixup(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup, GLuint reg)
+{
+    if(is_same_fixup(fixup, color_fixup_rg))
+    {
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, GL_NONE,
+                reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_BLUE_BIT_ATI, GL_NONE,
+                GL_ONE, GL_NONE, GL_NONE);
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_ALPHA, GL_NONE,
+                GL_ONE, GL_NONE, GL_NONE);
+    }
+    else if(is_same_fixup(fixup, color_fixup_rgl))
+    {
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, GL_NONE,
+                reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
+    }
+    else if (is_same_fixup(fixup, color_fixup_rgba))
+    {
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_NONE, GL_NONE,
+                reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
+        wrap_op1(gl_info, GL_MOV_ATI, reg, GL_ALPHA, GL_NONE,
+                reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
+    }
+    else
+    {
+        /* Should not happen - atifs_color_fixup_supported refuses other fixups. */
+        ERR("Unsupported color fixup.\n");
+    }
+}
+
 static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const struct wined3d_gl_info *gl_info)
 {
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
@@ -491,13 +554,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
             swizzle = GL_SWIZZLE_STQ_DQ_ATI;
         }
 
-        if ((op[stage].carg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || (op[stage].carg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || (op[stage].carg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || (op[stage].aarg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || (op[stage].aarg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || (op[stage].aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
-                || op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA)
+        if (op_reads_texture(&op[stage]))
         {
             if (stage > 0
                     && (op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
@@ -545,6 +602,12 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
             dstreg = GL_REG_0_ATI;
         }
 
+        if (op[stage].cop == WINED3D_TOP_BUMPENVMAP || op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+        {
+            /* Those are handled in the first pass of the shader (generation pass 1 and 2) already */
+            continue;
+        }
+
         arg0 = register_for_arg(op[stage].carg0, gl_info, stage, &argmod0, &rep0, tmparg);
         arg1 = register_for_arg(op[stage].carg1, gl_info, stage, &argmod1, &rep1, tmparg);
         arg2 = register_for_arg(op[stage].carg2, gl_info, stage, &argmod2, &rep2, tmparg);
@@ -552,6 +615,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
         argmodextra = GL_NONE;
         extrarg = GL_NONE;
 
+        if (op_reads_texture(&op[stage]) && !is_identity_fixup(op[stage].color_fixup))
+            atifs_color_fixup(gl_info, op[stage].color_fixup, GL_REG_0_ATI + stage);
+
         switch (op[stage].cop)
         {
             case WINED3D_TOP_SELECT_ARG2:
@@ -683,11 +749,6 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                          arg2, rep2, argmod2);
                 break;
 
-            case WINED3D_TOP_BUMPENVMAP:
-            case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
-                /* Those are handled in the first pass of the shader(generation pass 1 and 2) already */
-                break;
-
             default: FIXME("Unhandled color operation %d on stage %d\n", op[stage].cop, stage);
         }
 
@@ -1196,9 +1257,8 @@ static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
     }
 
     /* We only support sign fixup of the first two channels. */
-    if (fixup.x_source == CHANNEL_SOURCE_X && fixup.y_source == CHANNEL_SOURCE_Y
-            && fixup.z_source == CHANNEL_SOURCE_Z && fixup.w_source == CHANNEL_SOURCE_W
-            && !fixup.z_sign_fixup && !fixup.w_sign_fixup)
+    if (is_identity_fixup(fixup) || is_same_fixup(fixup, color_fixup_rg)
+            || is_same_fixup(fixup, color_fixup_rgl) || is_same_fixup(fixup, color_fixup_rgba))
     {
         TRACE("[OK]\n");
         return TRUE;
-- 
2.3.3




More information about the wine-patches mailing list