Tobias Jakobi : wined3d: GLSL: Implement texrect coord fixup.

Alexandre Julliard julliard at winehq.org
Tue Mar 31 12:19:21 CDT 2009


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

Author: Tobias Jakobi <liquid.acid at gmx.net>
Date:   Thu Mar 26 03:19:41 2009 +0100

wined3d: GLSL: Implement texrect coord fixup.

---

 dlls/wined3d/glsl_shader.c |   53 +++++++++++++++++++++++++++++++++++++++++++-
 dlls/wined3d/state.c       |   17 ++++++++++++-
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index da0b1a8..c92f99b 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -100,6 +100,7 @@ struct glsl_shader_prog_link {
     GLint                       vuniformI_locations[MAX_CONST_I];
     GLint                       puniformI_locations[MAX_CONST_I];
     GLint                       posFixup_location;
+    GLint                       rectFixup_location[MAX_FRAGMENT_SAMPLERS];
     GLint                       bumpenvmat_location[MAX_TEXTURES];
     GLint                       luminancescale_location[MAX_TEXTURES];
     GLint                       luminanceoffset_location[MAX_TEXTURES];
@@ -587,6 +588,24 @@ static void shader_glsl_load_constants(
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
+
+        /* Constant loading for texture rect coord fixup. */
+        if (prog->ps_args.texrect_fixup) {
+            UINT fixup = prog->ps_args.texrect_fixup;
+
+            for (i = 0; fixup; fixup >>= 1, ++i) {
+                if (-1 != prog->rectFixup_location[i]) {
+                    const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
+                    if (!tex) {
+                        FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n");
+                        continue;
+                    } else {
+                        const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
+                        GL_EXTCALL(glUniform2fvARB(prog->rectFixup_location[i], 1, tex_dim));
+                    }
+                }
+            }
+        }
     }
 
     if (priv->next_constant_version == UINT_MAX)
@@ -774,6 +793,14 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                     } else {
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
+
+                    if(ps_args->texrect_fixup & (1 << i)) {
+                        /* RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
+                         * while D3D has them in the (normalized) [0,1]x[0,1] range.
+                         * samplerRectFixup stores texture dimensions and is updated through
+                         * shader_glsl_load_constants when the sampler changes. */
+                        shader_addline(buffer, "uniform vec2 %csamplerRectFixup%u;\n", prefix, i);
+                    }
                     break;
                 case WINED3DSTT_CUBE:
                     shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i);
@@ -1475,6 +1502,7 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR
     const char *sampler_base;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
+    BOOL rect_fixup = FALSE;
     va_list args;
 
     shader_glsl_get_swizzle(swizzle, FALSE, arg->dst, dst_swizzle);
@@ -1483,6 +1511,14 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) arg->shader;
         fixup = This->cur_args->color_fixup[sampler];
         sampler_base = "Psampler";
+
+        if(This->cur_args->texrect_fixup & (1 << sampler)) {
+            if(bias) {
+                FIXME("Biased sampling from RECT textures is unsupported\n");
+            } else {
+                rect_fixup = TRUE;
+            }
+        }
     } else {
         sampler_base = "Vsampler";
         fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
@@ -1499,7 +1535,11 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const SHADER_OPCODE_AR
     if(bias) {
         shader_addline(arg->buffer, ", %s)%s);\n", bias, dst_swizzle);
     } else {
-        shader_addline(arg->buffer, ")%s);\n", dst_swizzle);
+        if (rect_fixup) {
+            shader_addline(arg->buffer, " * PsamplerRectFixup%u)%s);\n", sampler, dst_swizzle);
+        } else {
+            shader_addline(arg->buffer, ")%s);\n", dst_swizzle);
+        }
     }
 
     if(!is_identity_fixup(fixup)) {
@@ -3479,6 +3519,17 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
         }
     }
 
+    if (use_ps && ps_compile_args.texrect_fixup) {
+        char name[32];
+        for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
+            if (ps_compile_args.texrect_fixup & (1 << i)) {
+                sprintf(name, "PsamplerRectFixup%u", i);
+                entry->rectFixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
+            } else {
+                entry->rectFixup_location[i] = -1;
+            }
+        }
+    }
 
     entry->posFixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup"));
     entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 0953042..2aa2b78 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3022,8 +3022,12 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
         if(generated) {
             FIXME("Non-power2 texture being used with generated texture coords\n");
         }
-        TRACE("Non power two matrix multiply fixup\n");
-        glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
+        /* NP2 texcoord fixup is implemented for pixelshaders (currently only in GLSL backend) so
+           only enable the fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
+        if (!use_ps(stateblock)) {
+            TRACE("Non power two matrix multiply fixup\n");
+            glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
+        }
     }
 }
 
@@ -3375,6 +3379,15 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
             }
         }
+
+        /* Trigger shader constant reloading (for NP2 texcoord fixup)
+         * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */
+        if (!tex_impl->baseTexture.pow2Matrix_identity && use_ps(stateblock)) {
+            IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice;
+            /* FIXME: add something like shader_load_rectfixup_consts to the backend to only reload the
+             * constants that are used for the fixup (and not the other ones too) */
+            d3ddevice->shader_backend->shader_load_constants((IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
+        }
     } else if(mapped_stage < GL_LIMITS(textures)) {
         if(sampler < stateblock->lowest_disabled_stage) {
             /* TODO: What should I do with pixel shaders here ??? */




More information about the wine-cvs mailing list