[PATCH 1/2] wined3d: Handle texture types via ps/vs_compile_args

Stefan Dösinger stefan at codeweavers.com
Wed Apr 10 06:39:45 CDT 2013


This patch only changes the way the texture types are fed into the
shader generation code. Generating the proper shader code (hardcoded
values instead of relying on the dummy textures) is a task I've left for
Matteo, who worked on this problem before.

This patch originates from my work-in-progress command stream work. It
is one of the few that I think makes sense on its own.
---
 dlls/wined3d/arb_program_shader.c | 40 +++++++++++++++----
 dlls/wined3d/glsl_shader.c        | 54 ++++++++++++++++++++++---
 dlls/wined3d/shader.c             | 84 ++++++++++++++++++++++++++++++++-------
 dlls/wined3d/wined3d_private.h    | 18 +++++----
 4 files changed, 161 insertions(+), 35 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 7e695fd..b24da49 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1368,31 +1368,45 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
 {
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
-    const struct wined3d_shader *shader = ins->ctx->shader;
-    const struct wined3d_texture *texture;
     const char *tex_type;
     BOOL np2_fixup = FALSE;
-    struct wined3d_device *device = shader->device;
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     const char *mod;
     BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+    enum tex_types bound_tex_type;
 
     /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
     if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
 
+    if (pshader)
+        bound_tex_type = priv->cur_ps_args->super.tex_type[sampler_idx];
+    else
+        bound_tex_type = priv->cur_vs_args->super.tex_type[sampler_idx - MAX_FRAGMENT_SAMPLERS];
+
     switch(sampler_type) {
         case WINED3DSTT_1D:
             tex_type = "1D";
+            if (bound_tex_type != tex_1d)
+            {
+                WARN("Bound texture type does not match shader code\n");
+            }
             break;
 
         case WINED3DSTT_2D:
-            texture = device->stateBlock->state.textures[sampler_idx];
-            if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
+            if (bound_tex_type == tex_rect)
             {
                 tex_type = "RECT";
-            } else {
+            }
+            else if (bound_tex_type == tex_2d)
+            {
                 tex_type = "2D";
             }
+            else
+            {
+                WARN("Bound texture type does not match shader code\n");
+                tex_type = "2D";
+            }
+
             if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
             {
                 if (priv->cur_np2fixup_info->super.active & (1 << sampler_idx))
@@ -1405,10 +1419,18 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
 
         case WINED3DSTT_VOLUME:
             tex_type = "3D";
+            if (bound_tex_type != tex_3d)
+            {
+                WARN("Bound texture type does not match shader code\n");
+            }
             break;
 
         case WINED3DSTT_CUBE:
             tex_type = "CUBE";
+            if (bound_tex_type != tex_cube)
+            {
+                WARN("Bound texture type does not match shader code\n");
+            }
             break;
 
         default:
@@ -3327,6 +3349,8 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i
 
     static const char * const blt_fprograms_full[tex_type_count] =
     {
+        /* tex_none */
+        NULL,
         /* tex_1d */
         NULL,
         /* tex_2d */
@@ -3353,6 +3377,8 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i
 
     static const char * const blt_fprograms_masked[tex_type_count] =
     {
+        /* tex_none */
+        NULL,
         /* tex_1d */
         NULL,
         /* tex_2d */
@@ -4352,7 +4378,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
 
     shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
 
-    pixelshader_update_samplers(&shader->reg_maps, device->stateBlock->state.textures);
+    pixelshader_update_samplers(&shader->reg_maps, &args->super);
 
     if (!shader_buffer_init(&buffer))
     {
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index a840a5d..fb08e4f 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -947,6 +947,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     const struct wined3d_shader_version *version = &reg_maps->shader_version;
     const struct wined3d_state *state = &shader->device->stateBlock->state;
     const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
+    const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_fb_state *fb = &shader->device->fb;
     unsigned int i, extra_constants_needed = 0;
@@ -1058,39 +1059,77 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
         if (reg_maps->sampler_type[i])
         {
             BOOL shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
-            const struct wined3d_texture *texture;
+            enum tex_types tex_type;
+
+            if (version->type == WINED3D_SHADER_TYPE_PIXEL)
+                tex_type = ps_args->tex_type[i];
+            else if (version->type == WINED3D_SHADER_TYPE_VERTEX)
+                tex_type = vs_args->tex_type[i];
+            else
+            {
+                FIXME("Texture type for shader type %u\n", version->type);
+                switch (reg_maps->sampler_type[i])
+                {
+                    case WINED3DSTT_1D:
+                        tex_type = tex_1d;
+                        break;
+                    case WINED3DSTT_2D:
+                        tex_type = tex_2d;
+                        break;
+                    case WINED3DSTT_VOLUME:
+                        tex_type = tex_3d;
+                        break;
+                    case WINED3DSTT_CUBE:
+                        tex_type = tex_cube;
+                        break;
+                    default:
+                        tex_type = tex_none;
+                        break;
+                }
+            }
 
             switch (reg_maps->sampler_type[i])
             {
                 case WINED3DSTT_1D:
+                    if (tex_type != tex_1d)
+                        WARN("Bound texture type does not match shader code\n");
+
                     if (shadow_sampler)
                         shader_addline(buffer, "uniform sampler1DShadow %s_sampler%u;\n", prefix, i);
                     else
                         shader_addline(buffer, "uniform sampler1D %s_sampler%u;\n", prefix, i);
                     break;
                 case WINED3DSTT_2D:
-                    texture = state->textures[i];
+                    if (tex_type != tex_2d && tex_type != tex_rect)
+                        WARN("Bound texture type does not match shader code\n");
+
                     if (shadow_sampler)
                     {
-                        if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
+                        if (tex_type == tex_rect)
                             shader_addline(buffer, "uniform sampler2DRectShadow %s_sampler%u;\n", prefix, i);
                         else
                             shader_addline(buffer, "uniform sampler2DShadow %s_sampler%u;\n", prefix, i);
                     }
                     else
                     {
-                        if (texture && texture->target == GL_TEXTURE_RECTANGLE_ARB)
+                        if (tex_type == tex_rect)
                             shader_addline(buffer, "uniform sampler2DRect %s_sampler%u;\n", prefix, i);
                         else
                             shader_addline(buffer, "uniform sampler2D %s_sampler%u;\n", prefix, i);
                     }
                     break;
                 case WINED3DSTT_CUBE:
+                    if (tex_type != tex_cube)
+                        WARN("Bound texture type does not match shader code\n");
+
                     if (shadow_sampler)
                         FIXME("Unsupported Cube shadow sampler.\n");
                     shader_addline(buffer, "uniform samplerCube %s_sampler%u;\n", prefix, i);
                     break;
                 case WINED3DSTT_VOLUME:
+                    if (tex_type != tex_3d)
+                        WARN("Bound texture type does not match shader code\n");
+
                     if (shadow_sampler)
                         FIXME("Unsupported 3D shadow sampler.\n");
                     shader_addline(buffer, "uniform sampler3D %s_sampler%u;\n", prefix, i);
@@ -4626,7 +4665,6 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
         struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
         const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
 {
-    struct wined3d_state *state = &shader->device->stateBlock->state;
     struct glsl_ps_compiled_shader *gl_shaders, *new_array;
     struct glsl_shader_private *shader_data;
     struct ps_np2fixup_info *np2fixup;
@@ -4689,7 +4727,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
     memset(np2fixup, 0, sizeof(*np2fixup));
     *np2fixup_info = args->np2_fixup ? np2fixup : NULL;
 
-    pixelshader_update_samplers(&shader->reg_maps, state->textures);
+    pixelshader_update_samplers(&shader->reg_maps, args);
 
     shader_buffer_clear(buffer);
     ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
@@ -5705,6 +5743,8 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
 
     static const char * const blt_pshaders_full[tex_type_count] =
     {
+        /* tex_none */
+        NULL,
         /* tex_1d */
         NULL,
         /* tex_2d */
@@ -5735,6 +5775,8 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
 
     static const char * const blt_pshaders_masked[tex_type_count] =
     {
+        /* tex_none */
+        NULL,
         /* tex_1d */
         NULL,
         /* tex_2d */
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 692e5b2..d2aa92e 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1782,11 +1782,49 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
 void find_vs_compile_args(const struct wined3d_state *state,
         const struct wined3d_shader *shader, struct vs_compile_args *args)
 {
+    unsigned int i;
+    const struct wined3d_texture *texture;
+
     args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE]
             == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
     args->clip_enabled = state->render_states[WINED3D_RS_CLIPPING]
             && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
     args->swizzle_map = shader->device->strided_streams.swizzle_map;
+
+    for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
+    {
+        if (!shader->reg_maps.sampler_type[i])
+        {
+            args->tex_type[i] = tex_none;
+            continue;
+        }
+
+        texture = state->textures[i + MAX_FRAGMENT_SAMPLERS];
+        if (!texture)
+        {
+            args->tex_type[i] = tex_none;
+            continue;
+        }
+
+        switch (texture->target)
+        {
+            case GL_TEXTURE_RECTANGLE_ARB:
+                args->tex_type[i] = tex_rect;
+                break;
+            case GL_TEXTURE_2D:
+                args->tex_type[i] = tex_2d;
+                break;
+            case GL_TEXTURE_3D:
+                args->tex_type[i] = tex_3d;
+                break;
+            case GL_TEXTURE_CUBE_MAP_ARB:
+                args->tex_type[i] = tex_cube;
+                break;
+            default:
+                FIXME("Unrecognized texture type %#x, using 2D.\n", texture->target);
+                args->tex_type[i] = tex_2d;
+        }
+    }
 }
 
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
@@ -2072,6 +2110,7 @@ void find_ps_compile_args(const struct wined3d_state *state,
         if (!texture)
         {
             args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
+            args->tex_type[i] = tex_none;
             continue;
         }
         args->color_fixup[i] = texture->resource.format->color_fixup;
@@ -2082,6 +2121,26 @@ void find_ps_compile_args(const struct wined3d_state *state,
         /* Flag samplers that need NP2 texcoord fixup. */
         if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
             args->np2_fixup |= (1 << i);
+
+        switch (texture->target)
+        {
+            case GL_TEXTURE_RECTANGLE_ARB:
+                args->tex_type[i] = tex_rect;
+                break;
+            case GL_TEXTURE_2D:
+                args->tex_type[i] = tex_2d;
+                break;
+            case GL_TEXTURE_3D:
+                args->tex_type[i] = tex_3d;
+                break;
+            case GL_TEXTURE_CUBE_MAP_ARB:
+                args->tex_type[i] = tex_cube;
+                break;
+            default:
+                FIXME("Unrecognized texture type %#x, using 2D.\n", texture->target);
+                args->tex_type[i] = tex_2d;
+        }
+
     }
     if (shader->reg_maps.shader_version.major >= 3)
     {
@@ -2274,7 +2333,7 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
     return WINED3D_OK;
 }
 
-void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps, struct wined3d_texture * const *textures)
+void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps, const struct ps_compile_args *args)
 {
     enum wined3d_sampler_texture_type *sampler_type = reg_maps->sampler_type;
     unsigned int i;
@@ -2286,34 +2345,31 @@ void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps, struc
         /* We don't sample from this sampler. */
         if (!sampler_type[i]) continue;
 
-        if (!textures[i])
+        switch (args->tex_type[i])
         {
-            WARN("No texture bound to sampler %u, using 2D.\n", i);
-            sampler_type[i] = WINED3DSTT_2D;
-            continue;
-        }
+            case tex_none:
+                WARN("No texture bound to sampler %u, using 2D.\n", i);
+                sampler_type[i] = WINED3DSTT_2D;
+                break;
 
-        switch (textures[i]->target)
-        {
-            case GL_TEXTURE_RECTANGLE_ARB:
-            case GL_TEXTURE_2D:
+            case tex_2d:
+            case tex_rect:
                 /* We have to select between texture rectangles and 2D
                  * textures later because 2.0 and 3.0 shaders only have
                  * WINED3DSTT_2D as well. */
                 sampler_type[i] = WINED3DSTT_2D;
                 break;
 
-            case GL_TEXTURE_3D:
+            case tex_3d:
                 sampler_type[i] = WINED3DSTT_VOLUME;
                 break;
 
-            case GL_TEXTURE_CUBE_MAP_ARB:
+            case tex_cube:
                 sampler_type[i] = WINED3DSTT_CUBE;
                 break;
 
             default:
-                FIXME("Unrecognized texture type %#x, using 2D.\n", textures[i]->target);
-                sampler_type[i] = WINED3DSTT_2D;
+                ERR("Unexpected tex_type %u\n", args->tex_type[i]);
         }
     }
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index bdba525..9a92e46 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -716,12 +716,13 @@ struct shader_caps
 
 enum tex_types
 {
-    tex_1d       = 0,
-    tex_2d       = 1,
-    tex_3d       = 2,
-    tex_cube     = 3,
-    tex_rect     = 4,
-    tex_type_count = 5,
+    tex_none     = 0,
+    tex_1d       = 1,
+    tex_2d       = 2,
+    tex_3d       = 3,
+    tex_cube     = 4,
+    tex_rect     = 5,
+    tex_type_count = 6,
 };
 
 enum vertexprocessing_mode {
@@ -752,7 +753,7 @@ struct ps_compile_args {
     enum vertexprocessing_mode  vp_mode;
     enum fogmode                fog;
     WORD                        tex_transform; /* ps 1.0-1.3, 4 textures */
-    /* Texture types(2D, Cube, 3D) in ps 1.x */
+    enum tex_types              tex_type[MAX_FRAGMENT_SAMPLERS];
     WORD                        srgb_correction;
     WORD                        np2_fixup;
     /* Bitmap for NP2 texcoord fixups (16 samplers max currently).
@@ -770,6 +771,7 @@ struct vs_compile_args {
     BYTE                        fog_src;
     BYTE                        clip_enabled;
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
+    enum tex_types              tex_type[MAX_VERTEX_SAMPLERS];
 };
 
 enum wined3d_shader_mode
@@ -2636,7 +2638,7 @@ struct wined3d_shader
 };
 
 void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps,
-        struct wined3d_texture * const *textures) DECLSPEC_HIDDEN;
+        const struct ps_compile_args *args) DECLSPEC_HIDDEN;
 void find_ps_compile_args(const struct wined3d_state *state,
         const struct wined3d_shader *shader, struct ps_compile_args *args) DECLSPEC_HIDDEN;
 
-- 
1.8.1.5




More information about the wine-patches mailing list