[PATCH vkd3d] vkd3d-shader/hlsl: Unify texture and sampler allocation functions.

Matteo Bruni mbruni at codeweavers.com
Tue Nov 9 06:54:40 CST 2021


Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
Hacking a bit on the compiler helped. Register reservation /
allocation is actually in a much better shape than I thought,
functionality-wise. I still dislike the way object allocation is done
but there is no ground or reason for blocking patches on that account.

What do you think about this patch instead? Ugly?
Based on top of 219079.

 libs/vkd3d-shader/hlsl_codegen.c | 102 +++++++++++--------------------
 1 file changed, 36 insertions(+), 66 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index b802f3a2..7c0b0f95 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -1202,118 +1202,88 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
     }
 }
 
-static const struct hlsl_ir_var *get_reserved_sampler(struct hlsl_ctx *ctx, uint32_t index)
+static const struct hlsl_ir_var *get_reserved_object(struct hlsl_ctx *ctx, char type, uint32_t index)
 {
     const struct hlsl_ir_var *var;
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
     {
-        if (var->last_read && var->reg_reservation.type == 's' && var->reg_reservation.index == index)
+        if (var->last_read && var->reg_reservation.type == type && var->reg_reservation.index == index)
             return var;
     }
     return NULL;
 }
 
-static void allocate_samplers(struct hlsl_ctx *ctx)
+static const struct object_type_info
 {
-    struct hlsl_ir_var *var;
-    uint32_t index = 0;
-
-    LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
-    {
-        if (!var->last_read || var->data_type->type != HLSL_CLASS_OBJECT
-                || var->data_type->base_type != HLSL_TYPE_SAMPLER)
-            continue;
-
-        if (var->reg_reservation.type == 's')
-        {
-            const struct hlsl_ir_var *reserved_sampler = get_reserved_sampler(ctx, var->reg_reservation.index);
-
-            if (reserved_sampler && reserved_sampler != var)
-            {
-                hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
-                        "Multiple samplers bound to s%u.", var->reg_reservation.index);
-                hlsl_note(ctx, reserved_sampler->loc, VKD3D_SHADER_LOG_ERROR,
-                        "Sampler '%s' is already bound to s%u.", reserved_sampler->name,
-                        var->reg_reservation.index);
-            }
-
-            var->reg.id = var->reg_reservation.index;
-            var->reg.allocated = true;
-            TRACE("Allocated reserved %s to s%u.\n", var->name, index);
-        }
-        else if (!var->reg_reservation.type)
-        {
-            while (get_reserved_sampler(ctx, index))
-                ++index;
-
-            var->reg.id = index;
-            var->reg.allocated = true;
-            TRACE("Allocated %s to s%u.\n", var->name, index);
-            ++index;
-        }
-        else
-        {
-            hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
-                    "Samplers must be bound to register type 's'.");
-        }
-    }
+    enum hlsl_base_type type;
+    char *name;
+    char reg_name;
 }
+object_types[] =
+{
+    { HLSL_TYPE_SAMPLER, "sampler", 's' },
+    { HLSL_TYPE_TEXTURE, "texture", 't' },
+};
 
-static const struct hlsl_ir_var *get_reserved_texture(struct hlsl_ctx *ctx, uint32_t index)
+static const struct object_type_info *get_object_type_info(enum hlsl_base_type type)
 {
-    const struct hlsl_ir_var *var;
+    unsigned int i;
 
-    LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
-    {
-        if (var->last_read && var->reg_reservation.type == 't' && var->reg_reservation.index == index)
-            return var;
-    }
+    for (i = 0; i < ARRAY_SIZE(object_types); ++i)
+        if (type == object_types[i].type)
+            return &object_types[i];
+
+    WARN("No type info for object type %u.\n", type);
     return NULL;
 }
 
-static void allocate_textures(struct hlsl_ctx *ctx)
+static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type)
 {
+    const struct object_type_info *type_info = get_object_type_info(type);
     struct hlsl_ir_var *var;
     uint32_t index = 0;
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
     {
         if (!var->last_read || var->data_type->type != HLSL_CLASS_OBJECT
-                || var->data_type->base_type != HLSL_TYPE_TEXTURE)
+                || var->data_type->base_type != type)
             continue;
 
-        if (var->reg_reservation.type == 't')
+        if (var->reg_reservation.type == type_info->reg_name)
         {
-            const struct hlsl_ir_var *reserved_texture = get_reserved_texture(ctx, var->reg_reservation.index);
+            const struct hlsl_ir_var *reserved_object = get_reserved_object(ctx, type_info->reg_name,
+                    var->reg_reservation.index);
 
-            if (reserved_texture && reserved_texture != var)
+            if (reserved_object && reserved_object != var)
             {
                 hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
-                        "Multiple textures bound to t%u.", var->reg_reservation.index);
-                hlsl_note(ctx, reserved_texture->loc, VKD3D_SHADER_LOG_ERROR,
-                        "Texture '%s' is already bound to t%u.", reserved_texture->name,
+                        "Multiple %ss bound to %c%u.", type_info->name, type_info->reg_name,
                         var->reg_reservation.index);
+                hlsl_note(ctx, reserved_object->loc, VKD3D_SHADER_LOG_ERROR,
+                        "Object '%s' is already bound to %c%u.", reserved_object->name,
+                        type_info->reg_name, var->reg_reservation.index);
             }
 
             var->reg.id = var->reg_reservation.index;
             var->reg.allocated = true;
-            TRACE("Allocated reserved %s to t%u.\n", var->name, var->reg_reservation.index);
+            TRACE("Allocated reserved %s to %c%u.\n", var->name, type_info->reg_name, var->reg_reservation.index);
         }
         else if (!var->reg_reservation.type)
         {
-            while (get_reserved_texture(ctx, index))
+            while (get_reserved_object(ctx, type_info->reg_name, index))
                 ++index;
 
             var->reg.id = index;
             var->reg.allocated = true;
-            TRACE("Allocated %s to t%u.\n", var->name, index);
+            TRACE("Allocated %s to %c%u.\n", var->name, type_info->reg_name, index);
             ++index;
         }
         else
         {
             hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
-                    "Textures must be bound to register type 't'.");
+                    "Object of type '%s' must be bound to register type '%c'.",
+                    type_info->name, type_info->reg_name);
         }
     }
 }
@@ -1434,10 +1404,10 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
     else
     {
         allocate_buffers(ctx);
-        allocate_textures(ctx);
+        allocate_objects(ctx, HLSL_TYPE_TEXTURE);
     }
     allocate_semantic_registers(ctx);
-    allocate_samplers(ctx);
+    allocate_objects(ctx, HLSL_TYPE_SAMPLER);
 
     if (ctx->result)
         return ctx->result;
-- 
2.26.3




More information about the wine-devel mailing list