[PATCH 4/5] wined3d: Record the data type of shader resources.

Henri Verbeet hverbeet at codeweavers.com
Wed Dec 3 03:28:11 CST 2014


---
 dlls/wined3d/arb_program_shader.c |    2 +-
 dlls/wined3d/context.c            |   32 ++++++++++-----------
 dlls/wined3d/glsl_shader.c        |   16 +++++------
 dlls/wined3d/shader.c             |   56 ++++++++++++++++++++++++++++---------
 dlls/wined3d/shader_sm1.c         |    1 +
 dlls/wined3d/shader_sm4.c         |   36 ++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h    |   11 +++++++-
 7 files changed, 115 insertions(+), 39 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index a28b529..bc66c4a 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1390,7 +1390,7 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi
 static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
         const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
 {
-    enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_type[sampler_idx];
+    enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     const char *tex_type;
     BOOL np2_fixup = FALSE;
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 75161c6..4da8c7d 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2585,14 +2585,14 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context,
 
 static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
 {
-    const enum wined3d_shader_resource_type *resource_type =
-            state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type;
+    const struct wined3d_shader_resource_info *resource_info =
+            state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
     unsigned int i;
     const struct wined3d_d3d_info *d3d_info = context->d3d_info;
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     {
-        if (resource_type[i] && context->tex_unit_map[i] != i)
+        if (resource_info[i].type && context->tex_unit_map[i] != i)
         {
             context_map_stage(context, i, i);
             context_invalidate_state(context, STATE_SAMPLER(i));
@@ -2603,8 +2603,8 @@ static void context_map_psamplers(struct wined3d_context *context, const struct
 }
 
 static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
-        const enum wined3d_shader_resource_type *ps_resource_types,
-        const enum wined3d_shader_resource_type *vs_resource_types, DWORD unit)
+        const struct wined3d_shader_resource_info *ps_resource_info,
+        const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
 {
     DWORD current_mapping = context->rev_tex_unit_map[unit];
 
@@ -2616,25 +2616,25 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
     {
         /* Used by a fragment sampler */
 
-        if (!ps_resource_types)
+        if (!ps_resource_info)
         {
             /* No pixel shader, check fixed function */
             return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
         }
 
         /* Pixel shader, check the shader's sampler map */
-        return !ps_resource_types[current_mapping];
+        return !ps_resource_info[current_mapping].type;
     }
 
     /* Used by a vertex sampler */
-    return !vs_resource_types[current_mapping - MAX_FRAGMENT_SAMPLERS];
+    return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
 }
 
 static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
 {
-    const enum wined3d_shader_resource_type *vs_resource_type =
-            state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_type;
-    const enum wined3d_shader_resource_type *ps_resource_type = NULL;
+    const struct wined3d_shader_resource_info *vs_resource_info =
+            state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info;
+    const struct wined3d_shader_resource_info *ps_resource_info = NULL;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
     int i;
@@ -2643,12 +2643,12 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
      * resource's specific type. Otherwise we'd need to call
      * shader_update_samplers() here for 1.x pixelshaders. */
     if (ps)
-        ps_resource_type = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type;
+        ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
 
     for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
     {
         DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
-        if (vs_resource_type[i])
+        if (vs_resource_info[i].type)
         {
             if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
             {
@@ -2658,7 +2658,7 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
 
             while (start >= 0)
             {
-                if (context_unit_free_for_vs(context, ps_resource_type, vs_resource_type, start))
+                if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
                 {
                     context_map_stage(context, vsampler_idx, start);
                     context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
@@ -2930,7 +2930,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     {
         for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
         {
-            if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_type[i])
+            if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type)
                 context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i);
         }
     }
@@ -2939,7 +2939,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     {
         for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
         {
-            if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type[i])
+            if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type)
                 context_preload_texture(context, state, i);
         }
     }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index ea6f4c9..a351932 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1066,11 +1066,11 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     {
         BOOL shadow_sampler, tex_rect;
 
-        if (!reg_maps->resource_type[i])
+        if (!reg_maps->resource_info[i].type)
             continue;
 
         shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
-        switch (reg_maps->resource_type[i])
+        switch (reg_maps->resource_info[i].type)
         {
             case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
                 if (shadow_sampler)
@@ -1112,7 +1112,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
 
             default:
                 shader_addline(buffer, "uniform unsupported_sampler %s_sampler%u;\n", prefix, i);
-                FIXME("Unhandled resource type %#x.\n", reg_maps->resource_type[i]);
+                FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type);
                 break;
         }
     }
@@ -1134,10 +1134,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
 
         for (i = 0; i < shader->limits->sampler; ++i)
         {
-            if (!reg_maps->resource_type[i] || !(ps_args->np2_fixup & (1 << i)))
+            if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1 << i)))
                 continue;
 
-            if (reg_maps->resource_type[i] != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
+            if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
             {
                 FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
                 continue;
@@ -1890,7 +1890,7 @@ static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op)
 static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx,
         DWORD resource_idx, DWORD flags, struct glsl_sample_function *sample_function)
 {
-    enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_type[resource_idx];
+    enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
     const struct wined3d_gl_info *gl_info = ctx->gl_info;
     BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
             && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << resource_idx));
@@ -3468,7 +3468,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
     {
         DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
                 & WINED3D_PSARGS_TEXTRANSFORM_MASK;
-        enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_type[resource_idx];
+        enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
 
         /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
         if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
@@ -3507,7 +3507,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
     else
     {
         if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
-                && ins->ctx->reg_maps->resource_type[resource_idx] != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
+                && ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
         {
             /* ps 2.0 texldp instruction always divides by the fourth component. */
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index b0aabd9..6531803 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -664,12 +664,13 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
 
                 case WINED3DSPR_SAMPLER:
                 case WINED3DSPR_RESOURCE:
-                    if (reg_idx >= ARRAY_SIZE(reg_maps->resource_type))
+                    if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info))
                     {
                         ERR("Invalid resource index %u.\n", reg_idx);
                         break;
                     }
-                    reg_maps->resource_type[reg_idx] = semantic->resource_type;
+                    reg_maps->resource_info[reg_idx].type = semantic->resource_type;
+                    reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
                     break;
 
                 default:
@@ -897,17 +898,20 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                             || ins.handler_idx == WINED3DSIH_TEXREG2GB
                             || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
                 {
+                    unsigned int reg_idx = ins.dst[i].reg.idx[0].offset;
+
                     TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
-                    reg_maps->resource_type[ins.dst[i].reg.idx[0].offset] = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
+                    reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
+                    reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
 
                     /* texbem is only valid with < 1.4 pixel shaders */
                     if (ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML)
                     {
-                        reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
+                        reg_maps->bumpmat |= 1 << reg_idx;
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
-                            reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
+                            reg_maps->luminanceparams |= 1 << reg_idx;
                         }
                     }
                 }
@@ -1063,6 +1067,32 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
                 TRACE("unknown");
                 break;
         }
+        switch (semantic->resource_data_type)
+        {
+            case WINED3D_DATA_FLOAT:
+                TRACE(" (float)");
+                break;
+
+            case WINED3D_DATA_INT:
+                TRACE(" (int)");
+                break;
+
+            case WINED3D_DATA_UINT:
+                TRACE(" (uint)");
+                break;
+
+            case WINED3D_DATA_UNORM:
+                TRACE(" (unorm)");
+                break;
+
+            case WINED3D_DATA_SNORM:
+                TRACE(" (snorm)");
+                break;
+
+            default:
+                TRACE(" (unknown)");
+                break;
+        }
     }
     else
     {
@@ -2179,7 +2209,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
 
                 if (!state->shader[WINED3D_SHADER_TYPE_VERTEX])
                 {
-                    enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_type[i];
+                    enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_info[i].type;
                     unsigned int j;
                     unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
                     DWORD max_valid = WINED3D_TTFF_COUNT4;
@@ -2229,7 +2259,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
         {
             const struct wined3d_texture *texture = state->textures[i];
 
-            if (!shader->reg_maps.resource_type[i])
+            if (!shader->reg_maps.resource_info[i].type)
                 continue;
 
             /* Treat unbound textures as 2D. The dummy texture will provide
@@ -2258,7 +2288,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
     {
-        if (!shader->reg_maps.resource_type[i])
+        if (!shader->reg_maps.resource_info[i].type)
             continue;
 
         texture = state->textures[i];
@@ -2429,7 +2459,7 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
 void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types)
 {
     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
-    enum wined3d_shader_resource_type *resource_type = reg_maps->resource_type;
+    struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info;
     unsigned int i;
 
     if (reg_maps->shader_version.major != 1) return;
@@ -2437,21 +2467,21 @@ void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_t
     for (i = 0; i < shader->limits->sampler; ++i)
     {
         /* We don't sample from this sampler. */
-        if (!resource_type[i])
+        if (!resource_info[i].type)
             continue;
 
         switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
         {
             case WINED3D_SHADER_TEX_2D:
-                resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
                 break;
 
             case WINED3D_SHADER_TEX_3D:
-                resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
                 break;
 
             case WINED3D_SHADER_TEX_CUBE:
-                resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
+                resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
                 break;
         }
     }
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index 3d9050d..0465002 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -646,6 +646,7 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se
     {
         semantic->resource_type = resource_type_table[resource_type];
     }
+    semantic->resource_data_type = WINED3D_DATA_FLOAT;
     shader_parse_dst_param(dst_token, NULL, &semantic->reg);
 }
 
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index b3bf156..046b252 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -185,6 +185,15 @@ enum wined3d_sm4_resource_type
     WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY  = 0x9,
 };
 
+enum wined3d_sm4_data_type
+{
+    WINED3D_SM4_DATA_UNORM  = 0x1,
+    WINED3D_SM4_DATA_SNORM  = 0x2,
+    WINED3D_SM4_DATA_INT    = 0x3,
+    WINED3D_SM4_DATA_UINT   = 0x4,
+    WINED3D_SM4_DATA_FLOAT  = 0x5,
+};
+
 struct wined3d_shader_src_param_entry
 {
     struct list entry;
@@ -356,6 +365,16 @@ static const enum wined3d_shader_resource_type resource_type_table[] =
     /* WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY */    WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
 };
 
+static const enum wined3d_data_type data_type_table[] =
+{
+    /* 0 */                         WINED3D_DATA_FLOAT,
+    /* WINED3D_SM4_DATA_UNORM */    WINED3D_DATA_UNORM,
+    /* WINED3D_SM4_DATA_SNORM */    WINED3D_DATA_SNORM,
+    /* WINED3D_SM4_DATA_INT */      WINED3D_DATA_INT,
+    /* WINED3D_SM4_DATA_UINT */     WINED3D_DATA_UINT,
+    /* WINED3D_SM4_DATA_FLOAT */    WINED3D_DATA_FLOAT,
+};
+
 static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
         enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
 
@@ -779,6 +798,8 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
     if (opcode == WINED3D_SM4_OP_DCL_RESOURCE)
     {
         enum wined3d_sm4_resource_type resource_type;
+        enum wined3d_sm4_data_type data_type;
+        DWORD components;
 
         resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
         if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
@@ -791,6 +812,21 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
             ins->declaration.semantic.resource_type = resource_type_table[resource_type];
         }
         shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_RESOURCE, &ins->declaration.semantic.reg);
+
+        components = *p++;
+        if ((components & 0xfff0) != (components & 0xf) * 0x1110)
+            FIXME("Components (%#x) have different data types.\n", components);
+        data_type = components & 0xf;
+
+        if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
+        {
+            FIXME("Unhandled data type %#x.\n", data_type);
+            ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
+        }
+        else
+        {
+            ins->declaration.semantic.resource_data_type = data_type_table[data_type];
+        }
     }
     else if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
     {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a1e5dea..e8e649a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -347,6 +347,8 @@ enum wined3d_data_type
     WINED3D_DATA_RESOURCE,
     WINED3D_DATA_SAMPLER,
     WINED3D_DATA_UINT,
+    WINED3D_DATA_UNORM,
+    WINED3D_DATA_SNORM,
 };
 
 enum wined3d_immconst_type
@@ -574,6 +576,12 @@ struct wined3d_shader_version
     BYTE minor;
 };
 
+struct wined3d_shader_resource_info
+{
+    enum wined3d_shader_resource_type type;
+    enum wined3d_data_type data_type;
+};
+
 #define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
 
 struct wined3d_shader_reg_maps
@@ -593,7 +601,7 @@ struct wined3d_shader_reg_maps
     WORD local_bool_consts;                 /* MAX_CONST_B, 16 */
     UINT cb_sizes[WINED3D_MAX_CBS];
 
-    enum wined3d_shader_resource_type resource_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+    struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
     BYTE bumpmat;                           /* MAX_TEXTURES, 8 */
     BYTE luminanceparams;                   /* MAX_TEXTURES, 8 */
 
@@ -679,6 +687,7 @@ struct wined3d_shader_semantic
     enum wined3d_decl_usage usage;
     UINT usage_idx;
     enum wined3d_shader_resource_type resource_type;
+    enum wined3d_data_type resource_data_type;
     struct wined3d_shader_dst_param reg;
 };
 
-- 
1.7.10.4




More information about the wine-patches mailing list