wined3d: Keep track of texture transformation states in compiled pixel shaders. [try 3]

Matteo Bruni matteo.mystral at gmail.com
Thu Sep 30 05:25:41 CDT 2010


-------------- next part --------------
From fd2eaac110446e737b98e24eb5979c952019796d Mon Sep 17 00:00:00 2001
From: Matteo Bruni <mbruni at codeweavers.com>
Date: Thu, 30 Sep 2010 12:16:16 +0200
Subject: wined3d: Keep track of texture transformation states in compiled pixel shaders.

---
 dlls/wined3d/arb_program_shader.c |   26 +++++++++++++-------------
 dlls/wined3d/glsl_shader.c        |   18 ++++++++++--------
 dlls/wined3d/shader.c             |   13 ++++++++++++-
 dlls/wined3d/wined3d_private.h    |    9 +++++++--
 4 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 9be5cd2..dec7a10 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1884,8 +1884,7 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
-    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
@@ -1927,8 +1926,8 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
     {
         DWORD flags = 0;
         if (reg_sampler_code < MAX_TEXTURES)
-            flags = deviceImpl->stateBlock->state.texture_states[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
-        if (flags & WINED3DTTFF_PROJECTED)
+            flags = priv->cur_ps_args->super.tex_transform >> reg_sampler_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+        if (flags & WINED3D_PSARGS_PROJECTED)
             myflags |= TEX_PROJ;
     }
     else if (shader_version < WINED3D_SHADER_VERSION(2,0))
@@ -1977,9 +1976,7 @@ static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
      struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
-     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
-     DWORD flags;
+     DWORD flags = 0;
 
      DWORD reg1 = ins->dst[0].reg.idx;
      char dst_str[50];
@@ -1991,8 +1988,12 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
      /* Move .x first in case src_str is "TA" */
      shader_addline(buffer, "MOV TA.y, %s.x;\n", src_str);
      shader_addline(buffer, "MOV TA.x, %s.w;\n", src_str);
-     flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->state.texture_states[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-     shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+     if (reg1 < MAX_TEXTURES)
+     {
+         struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+         flags = priv->cur_ps_args->super.tex_transform >> reg1 * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+     }
+     shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
 }
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
@@ -2025,8 +2026,7 @@ static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
-    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)shader->baseShader.device;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char reg_coord[40], dst_reg[50], src_reg[50];
@@ -2058,8 +2058,8 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
     /* with projective textures, texbem only divides the static texture coord, not the displacement,
      * so we can't let the GL handle this.
      */
-    if (device->stateBlock->state.texture_states[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
-            & WINED3DTTFF_PROJECTED)
+    if ((priv->cur_ps_args->super.tex_transform >> reg_dest_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+            & WINED3D_PSARGS_PROJECTED)
     {
         shader_addline(buffer, "RCP TB.w, %s.w;\n", reg_coord);
         shader_addline(buffer, "MUL TB.xy, %s, TB.w;\n", reg_coord);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 28a3350..b71a17e 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3031,13 +3031,15 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
 
     if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
-        DWORD flags = deviceImpl->stateBlock->state.texture_states[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
+        const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+        DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+                & WINED3D_PSARGS_TEXTRANSFORM_MASK;
         WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
 
         /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
-        if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) {
+        if (flags & WINED3D_PSARGS_PROJECTED && sampler_type != WINED3DSTT_CUBE) {
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
-            switch (flags & ~WINED3DTTFF_PROJECTED) {
+            switch (flags & ~WINED3D_PSARGS_PROJECTED) {
                 case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break;
                 case WINED3DTTFF_COUNT2: mask = WINED3DSP_WRITEMASK_1; break;
                 case WINED3DTTFF_COUNT3: mask = WINED3DSP_WRITEMASK_2; break;
@@ -3467,8 +3469,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
  */
 static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
-    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
+    const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param;
     DWORD sampler_idx;
@@ -3477,7 +3478,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     char coord_mask[6];
 
     sampler_idx = ins->dst[0].reg.idx;
-    flags = deviceImpl->stateBlock->state.texture_states[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
+    flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+            & WINED3D_PSARGS_TEXTRANSFORM_MASK;
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
@@ -3488,10 +3490,10 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     /* with projective textures, texbem only divides the static texture coord, not the displacement,
          * so we can't let the GL handle this.
          */
-    if (flags & WINED3DTTFF_PROJECTED) {
+    if (flags & WINED3D_PSARGS_PROJECTED) {
         DWORD div_mask=0;
         char coord_div_mask[3];
-        switch (flags & ~WINED3DTTFF_PROJECTED) {
+        switch (flags & ~WINED3D_PSARGS_PROJECTED) {
             case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break;
             case WINED3DTTFF_COUNT2: div_mask = WINED3DSP_WRITEMASK_1; break;
             case WINED3DTTFF_COUNT3: div_mask = WINED3DSP_WRITEMASK_2; break;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 3bbf5ed..81c7344 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2081,7 +2081,18 @@ void find_ps_compile_args(const struct wined3d_state *state,
         if(rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1;
     }
 
-    args->np2_fixup = 0;
+    if (shader->baseShader.reg_maps.shader_version.major == 1
+            && shader->baseShader.reg_maps.shader_version.minor <= 3)
+    {
+        for (i = 0; i < 4; ++i)
+        {
+            DWORD flags = stateblock->state.texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
+            DWORD tex_transform = flags & ~WINED3DTTFF_PROJECTED;
+            if (flags & WINED3DTTFF_PROJECTED)
+                tex_transform |= WINED3D_PSARGS_PROJECTED;
+            args->tex_transform |= tex_transform << i * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+        }
+    }
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1ab89c5..176cf44 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -677,13 +677,18 @@ enum fogmode {
 /* Stateblock dependent parameters which have to be hardcoded
  * into the shader code
  */
+
+#define WINED3D_PSARGS_PROJECTED 8
+#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT 4
+#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xf
+
 struct ps_compile_args {
     struct color_fixup_desc     color_fixup[MAX_FRAGMENT_SAMPLERS];
     enum vertexprocessing_mode  vp_mode;
     enum fogmode                fog;
-    /* Projected textures(ps 1.0-1.3) */
+    WORD                        tex_transform; /* ps 1.0-1.3, 4 textures */
     /* Texture types(2D, Cube, 3D) in ps 1.x */
-    BOOL                        srgb_correction;
+    WORD                        srgb_correction;
     WORD                        np2_fixup;
     /* Bitmap for NP2 texcoord fixups (16 samplers max currently).
        D3D9 has a limit of 16 samplers and the fixup is superfluous
-- 
1.7.2.2


More information about the wine-patches mailing list