[PATCH vkd3d 1/5] vkd3d-shader: Create a separate variable for uniforms.

Zebediah Figura zfigura at codeweavers.com
Wed Mar 24 16:12:27 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 libs/vkd3d-shader/hlsl_codegen.c | 50 ++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 21bd9ab8..ad183819 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -19,6 +19,42 @@
  */
 
 #include "hlsl.h"
+#include <stdio.h>
+
+/* Split uniforms into two variables representing the constant and temp
+ * registers, and copy the former to the latter, so that writes to uniforms
+ * work. */
+static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var)
+{
+    struct hlsl_ir_assignment *store;
+    struct hlsl_ir_var *const_var;
+    struct hlsl_ir_load *load;
+    char name[31];
+
+    sprintf(name, "<uniform-%.20s>", var->name);
+    if (!(const_var = hlsl_new_var(vkd3d_strdup(name), var->data_type, var->loc, NULL, var->reg_reservation)))
+    {
+        ctx->failed = true;
+        return;
+    }
+    list_add_head(&ctx->globals->vars, &const_var->scope_entry);
+    var->is_uniform = 0;
+    const_var->is_uniform = 1;
+
+    if (!(load = hlsl_new_var_load(const_var, var->loc)))
+    {
+        ctx->failed = true;
+        return;
+    }
+    list_add_head(instrs, &load->node.entry);
+
+    if (!(store = hlsl_new_simple_assignment(var, &load->node)))
+    {
+        ctx->failed = true;
+        return;
+    }
+    list_add_after(&load->node.entry, &store->node.entry);
+}
 
 static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *),
         struct list *instrs, void *context)
@@ -418,8 +454,22 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
 
 int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
 {
+    struct hlsl_ir_var *var;
+
     list_move_head(entry_func->body, &ctx->static_initializers);
 
+    LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
+    {
+        if (var->is_uniform)
+            prepend_uniform_copy(ctx, entry_func->body, var);
+    }
+
+    LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry)
+    {
+        if (var->is_uniform)
+            prepend_uniform_copy(ctx, entry_func->body, var);
+    }
+
     while (transform_ir(ctx, fold_redundant_casts, entry_func->body, NULL));
     while (transform_ir(ctx, split_struct_copies, entry_func->body, NULL));
     while (transform_ir(ctx, fold_constants, entry_func->body, NULL));
-- 
2.31.0




More information about the wine-devel mailing list