Zebediah Figura : vkd3d-shader: Create a separate variable for uniforms.
Alexandre Julliard
julliard at winehq.org
Tue Mar 30 14:57:57 CDT 2021
Module: vkd3d
Branch: master
Commit: 21fea55c2db6168b544853b588bd642fb8bbe445
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=21fea55c2db6168b544853b588bd642fb8bbe445
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Sun Mar 28 21:46:55 2021 +0200
vkd3d-shader: Create a separate variable for uniforms.
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
libs/vkd3d-shader/hlsl_codegen.c | 59 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 21bd9ab..e9f3699 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -19,6 +19,49 @@
*/
#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 vkd3d_string_buffer *name;
+ struct hlsl_ir_assignment *store;
+ struct hlsl_ir_var *const_var;
+ struct hlsl_ir_load *load;
+
+ if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers)))
+ {
+ ctx->failed = true;
+ return;
+ }
+ vkd3d_string_buffer_printf(name, "<uniform-%s>", var->name);
+ if (!(const_var = hlsl_new_var(vkd3d_strdup(name->buffer), var->data_type, var->loc, NULL, var->reg_reservation)))
+ {
+ vkd3d_string_buffer_release(&ctx->string_buffers, name);
+ ctx->failed = true;
+ return;
+ }
+ vkd3d_string_buffer_release(&ctx->string_buffers, name);
+ 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)
@@ -404,7 +447,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry)
{
- if (var->is_input_varying || var->is_uniform)
+ if (var->is_input_varying)
var->first_write = 1;
if (var->is_output_varying)
var->last_read = UINT_MAX;
@@ -418,8 +461,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));
More information about the wine-cvs
mailing list