[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