Matteo Bruni : wined3d: Use ARB_texture_swizzle for color fixups when possible.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 24 11:04:01 CDT 2016


Module: wine
Branch: master
Commit: 0ed39ad13db834525f35462f4c9deec1c61786aa
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0ed39ad13db834525f35462f4c9deec1c61786aa

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Wed Mar 23 21:19:10 2016 +0100

wined3d: Use ARB_texture_swizzle for color fixups when possible.

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/cs.c              |  4 +++-
 dlls/wined3d/glsl_shader.c     |  8 ++++----
 dlls/wined3d/shader.c          |  5 ++++-
 dlls/wined3d/texture.c         | 27 +++++++++++++++++++++++++++
 dlls/wined3d/utils.c           |  5 ++++-
 dlls/wined3d/wined3d_private.h |  6 ++++++
 6 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 910350d..0e6cc5b 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -634,6 +634,7 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha
 
 static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
 {
+    const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
     const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
     const struct wined3d_cs_set_texture *op = data;
     struct wined3d_texture *prev;
@@ -653,7 +654,8 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
             op->texture->sampler = op->stage;
 
         if (!prev || op->texture->target != prev->target
-                || !is_same_fixup(new_format->color_fixup, old_format->color_fixup)
+                || (!is_same_fixup(new_format->color_fixup, old_format->color_fixup)
+                && !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format)))
                 || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW))
             device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 8892d49..e6ef82a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2883,9 +2883,8 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
 
     shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
 
-    /* FIXME: We currently don't support fixups for vertex shaders or anything
-     * above SM3. Note that for SM4+ the sampler index doesn't have to match
-     * the resource index. */
+    /* If ARB_texture_swizzle is supported we don't need to do anything here.
+     * We actually rely on it for vertex shaders and SM4+. */
     if (version->type == WINED3D_SHADER_TYPE_PIXEL && version->major < 4)
     {
         const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
@@ -8035,7 +8034,8 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
     if (gl_info->glsl_version >= MAKEDWORD_VERSION(4, 30) && gl_info->supported[WINED3D_GL_VERSION_4_3])
         shader_model = 5;
     else if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50) && gl_info->supported[WINED3D_GL_VERSION_3_2]
-            && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS])
+            && gl_info->supported[ARB_SHADER_BIT_ENCODING] && gl_info->supported[ARB_SAMPLER_OBJECTS]
+            && gl_info->supported[ARB_TEXTURE_SWIZZLE])
         shader_model = 4;
     /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
      * texldd and texldl instructions. */
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 9aa0fa1..db30868 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2786,7 +2786,10 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
             args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
             continue;
         }
-        args->color_fixup[i] = texture->resource.format->color_fixup;
+        if (can_use_texture_swizzle(gl_info, texture->resource.format))
+            args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
+        else
+            args->color_fixup[i] = texture->resource.format->color_fixup;
 
         if (texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW)
             args->shadow |= 1u << i;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index feb6919..e163e83 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -219,6 +219,8 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_format *format = texture->resource.format;
+    const struct color_fixup_desc fixup = format->color_fixup;
     struct gl_texture *gl_tex;
     GLenum target;
 
@@ -330,6 +332,31 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
         gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
         checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)");
     }
+
+    if (!is_identity_fixup(fixup) && can_use_texture_swizzle(gl_info, format))
+    {
+        static const GLenum swizzle_source[] =
+        {
+            GL_ZERO,  /* CHANNEL_SOURCE_ZERO */
+            GL_ONE,   /* CHANNEL_SOURCE_ONE */
+            GL_RED,   /* CHANNEL_SOURCE_X */
+            GL_GREEN, /* CHANNEL_SOURCE_Y */
+            GL_BLUE,  /* CHANNEL_SOURCE_Z */
+            GL_ALPHA, /* CHANNEL_SOURCE_W */
+        };
+        struct
+        {
+            GLint x, y, z, w;
+        }
+        swizzle;
+
+        swizzle.x = swizzle_source[fixup.x_source];
+        swizzle.y = swizzle_source[fixup.y_source];
+        swizzle.z = swizzle_source[fixup.z_source];
+        swizzle.w = swizzle_source[fixup.w_source];
+        gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, &swizzle.x);
+        checkGLcall("glTexParameteriv(GL_TEXTURE_SWIZZLE_RGBA)");
+    }
 }
 
 /* Context activation is done by the caller. */
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 506bc07..df22e80 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -4840,7 +4840,10 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
 
         if ((texture = state->textures[i]))
         {
-            settings->op[i].color_fixup = texture->resource.format->color_fixup;
+            if (can_use_texture_swizzle(gl_info, texture->resource.format))
+                settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
+            else
+                settings->op[i].color_fixup = texture->resource.format->color_fixup;
             if (ignore_textype)
             {
                 settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a9d2a96..7b7b65b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3435,6 +3435,12 @@ static inline BOOL needs_srgb_write(const struct wined3d_context *context,
             && fb->render_targets[0] && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE;
 }
 
+static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format)
+{
+    return gl_info->supported[ARB_TEXTURE_SWIZZLE] && !is_complex_fixup(format->color_fixup)
+            && !is_scaling_fixup(format->color_fixup);
+}
+
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 




More information about the wine-cvs mailing list