From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Did a bunch of changes, mostly stylistic.
I dropped the existing sign-offs here and in some of the following patches since I changed enough of the code that I wouldn't feel those would still be valid.
Sorry it took me a while to review and fix up these patches and come up with a hopefully consistent patch series. I don't expect the whole series to go in in one go but I wanted to "show" the end result to possibly unblock anyone that wants to start preparing more patches on top (but I'd refrain from sending until this series is resolved one way or another :)).
This series should supersede or otherwise render invalid all the other pending vkd3d-shader/hlsl patches.
libs/vkd3d-shader/hlsl.c | 20 ++- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 217 ++++++++++++++++++++++++++++++- 3 files changed, 232 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9824c56d..8895f5bc 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1097,6 +1097,19 @@ const char *debug_hlsl_writemask(unsigned int writemask) return vkd3d_dbg_sprintf(".%s", string); }
+const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int size) +{ + static const char components[] = {'x', 'y', 'z', 'w'}; + char string[5]; + unsigned int i; + + assert(size <= ARRAY_SIZE(components)); + for (i = 0; i < size; ++i) + string[i] = components[(swizzle >> i * 2) & 3]; + string[size] = 0; + return vkd3d_dbg_sprintf(".%s", string); +} + static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant) { struct hlsl_type *type = constant->node.data_type; @@ -1278,18 +1291,15 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls unsigned int i;
dump_src(buffer, &swizzle->val); - vkd3d_string_buffer_printf(buffer, "."); if (swizzle->val.node->data_type->dimy > 1) { + vkd3d_string_buffer_printf(buffer, "."); for (i = 0; i < swizzle->node.data_type->dimx; ++i) vkd3d_string_buffer_printf(buffer, "_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf); } else { - static const char c[] = {'x', 'y', 'z', 'w'}; - - for (i = 0; i < swizzle->node.data_type->dimx; ++i) - vkd3d_string_buffer_printf(buffer, "%c", c[(swizzle->swizzle >> i * 2) & 0x3]); + vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_swizzle(swizzle->swizzle, swizzle->node.data_type->dimx)); } }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e7bdb45e..eb11b4ab 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -667,6 +667,7 @@ static inline struct hlsl_type *hlsl_get_numeric_type(const struct hlsl_ctx *ctx const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); const char *debug_hlsl_writemask(unsigned int writemask); +const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int count);
struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type); struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8b0eb9b3..d3957f89 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -237,6 +237,216 @@ static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) hlsl_free_instr(old); }
+struct copy_propagation_value +{ + struct hlsl_ir_node *node; + unsigned int component; +}; + +struct copy_propagation_var_def +{ + struct rb_entry entry; + struct hlsl_ir_var *var; + struct copy_propagation_value values[]; +}; + +struct copy_propagation_state +{ + struct rb_tree var_defs; +}; + +static int copy_propagation_var_def_compare(const void *key, const struct rb_entry *entry) +{ + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + uintptr_t key_int = (uintptr_t)key, entry_int = (uintptr_t)var_def->var; + + return (key_int > entry_int) - (key_int < entry_int); +} + +static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *context) +{ + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + + vkd3d_free(var_def); +} + +static struct copy_propagation_var_def *copy_propagation_get_var_def(struct copy_propagation_state *state, + struct hlsl_ir_var *var) +{ + struct rb_entry *entry = rb_get(&state->var_defs, var); + + if (entry) + return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + else + return NULL; +} + +static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx, + struct copy_propagation_state *state, struct hlsl_ir_var *var) +{ + struct rb_entry *entry = rb_get(&state->var_defs, var); + struct copy_propagation_var_def *var_def; + int res; + + if (entry) + return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + + if (!(var_def = hlsl_alloc(ctx, offsetof(struct copy_propagation_var_def, values[var->data_type->reg_size])))) + return NULL; + + var_def->var = var; + + res = rb_put(&state->var_defs, var, &var_def->entry); + assert(!res); + + return var_def; +} + +static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def) +{ + TRACE("Invalidate variable %s.\n", var_def->var->name); + memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size); +} + +static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int offset, + unsigned char writemask, struct hlsl_ir_node *node) +{ + unsigned int i, j = 0; + + for (i = 0; i < 4; ++i) + { + if (writemask & (1u << i)) + { + TRACE("Variable %s[%u] is written by instruction %p%s.\n", + var_def->var->name, offset + i, node, debug_hlsl_writemask(1u << i)); + var_def->values[offset + i].node = node; + var_def->values[offset + i].component = j++; + } + } +} + +static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_propagation_var_def *var_def, + unsigned int offset, unsigned int count, unsigned int *swizzle) +{ + struct hlsl_ir_node *node = NULL; + unsigned int i; + + assert(offset + count <= var_def->var->data_type->reg_size); + + *swizzle = 0; + + for (i = 0; i < count; ++i) + { + if (!node) + node = var_def->values[offset + i].node; + else if (node != var_def->values[offset + i].node) + return NULL; + *swizzle |= var_def->values[offset + i].component << i * 2; + } + + return node; +} + +static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, + struct copy_propagation_state *state) +{ + struct hlsl_ir_node *node = &load->node, *new_node; + struct copy_propagation_var_def *var_def; + struct hlsl_type *type = node->data_type; + struct hlsl_ir_swizzle *swizzle_node; + struct hlsl_deref *src = &load->src; + struct hlsl_ir_var *var = src->var; + unsigned int offset, swizzle; + + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + + if (!hlsl_offset_from_deref(src, &offset)) + return false; + + if (!(var_def = copy_propagation_get_var_def(state, var))) + return false; + + if (!(new_node = copy_propagation_compute_replacement(var_def, offset, type->dimx, &swizzle))) + { + TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx); + return false; + } + + TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n", + var->name, offset, offset + type->dimx, new_node, debug_hlsl_swizzle(swizzle, 4)); + if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, type->dimx, new_node, &node->loc))) + return false; + list_add_before(&node->entry, &swizzle_node->node.entry); + replace_node(node, &swizzle_node->node); + return true; +} + +static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + struct copy_propagation_state *state) +{ + struct copy_propagation_var_def *var_def; + struct hlsl_deref *lhs = &store->lhs; + struct hlsl_ir_var *var = lhs->var; + unsigned int offset; + + if (!(var_def = copy_propagation_create_var_def(ctx, state, var))) + return; + + if (hlsl_offset_from_deref(lhs, &offset)) + copy_propagation_set_value(var_def, offset, store->writemask, store->rhs.node); + else + copy_propagation_invalidate_whole_variable(var_def); +} + +static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct copy_propagation_state *state) +{ + struct hlsl_ir_node *instr, *next; + bool progress = false; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_LOAD: + progress |= copy_propagation_analyze_load(ctx, hlsl_ir_load(instr), state); + break; + + case HLSL_IR_STORE: + copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); + break; + + case HLSL_IR_IF: + FIXME("Copy propagation doesn't support conditionals yet, leaving.\n"); + return progress; + + case HLSL_IR_LOOP: + FIXME("Copy propagation doesn't support loops yet, leaving.\n"); + return progress; + + default: + break; + } + } + + return progress; +} + +static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + struct copy_propagation_state state; + bool progress; + + rb_init(&state.var_defs, copy_propagation_var_def_compare); + + progress = copy_propagation_transform_block(ctx, block, &state); + + rb_destroy(&state.var_defs, copy_propagation_var_def_destroy, NULL); + + return progress; +} + static bool is_vec1(const struct hlsl_type *type) { return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1); @@ -1421,7 +1631,12 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun progress |= transform_ir(ctx, split_struct_copies, body, NULL); } while (progress); - while (transform_ir(ctx, fold_constants, body, NULL)); + do + { + progress = transform_ir(ctx, fold_constants, body, NULL); + progress |= copy_propagation_execute(ctx, body); + } + while (progress); transform_ir(ctx, remove_trivial_swizzles, body, NULL);
if (ctx->profile->major_version < 4)
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Continue copy propagation after encountering an IF, rework to store the copy_propagation_state structs on the stack and search recursively.
libs/vkd3d-shader/hlsl_codegen.c | 142 ++++++++++++++++++++++++++++--- 1 file changed, 128 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index d3957f89..cbe546c3 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -253,6 +253,7 @@ struct copy_propagation_var_def struct copy_propagation_state { struct rb_tree var_defs; + struct copy_propagation_state *parent; };
static int copy_propagation_var_def_compare(const void *key, const struct rb_entry *entry) @@ -271,9 +272,12 @@ static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *conte }
static struct copy_propagation_var_def *copy_propagation_get_var_def(struct copy_propagation_state *state, - struct hlsl_ir_var *var) + const struct hlsl_ir_var *var) { - struct rb_entry *entry = rb_get(&state->var_defs, var); + struct rb_entry *entry; + + while (state && !(entry = rb_get(&state->var_defs, var))) + state = state->parent;
if (entry) return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); @@ -302,12 +306,6 @@ static struct copy_propagation_var_def *copy_propagation_create_var_def(struct h return var_def; }
-static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def) -{ - TRACE("Invalidate variable %s.\n", var_def->var->name); - memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size); -} - static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int offset, unsigned char writemask, struct hlsl_ir_node *node) { @@ -317,7 +315,7 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, { if (writemask & (1u << i)) { - TRACE("Variable %s[%u] is written by instruction %p%s.\n", + TRACE("Variable %s[%u] updated with value from %p%s.\n", var_def->var->name, offset + i, node, debug_hlsl_writemask(1u << i)); var_def->values[offset + i].node = node; var_def->values[offset + i].component = j++; @@ -325,6 +323,99 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, } }
+static void copy_propagation_invalidate_whole_variable(struct copy_propagation_state *state, + struct copy_propagation_var_def *var_def) +{ + const struct hlsl_ir_var *var = var_def->var; + + TRACE("Invalidate variable %s.\n", var->name); + while (state) + { + if ((var_def = copy_propagation_get_var_def(state, var))) + memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size); + state = state->parent; + } +} + +static void copy_propagation_invalidate_variable_partial(struct copy_propagation_state *state, + struct copy_propagation_var_def *var_def, unsigned int offset, unsigned char writemask) +{ + const struct hlsl_ir_var *var = var_def->var; + + TRACE("Invalidate variable %s[%u]%s.\n", var->name, offset, debug_hlsl_writemask(writemask)); + while (state) + { + if ((var_def = copy_propagation_get_var_def(state, var))) + copy_propagation_set_value(var_def, offset, writemask, NULL); + state = state->parent; + } +} + +static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct copy_propagation_state *state, + struct hlsl_block *block) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + struct copy_propagation_var_def *var_def; + struct hlsl_deref *lhs = &store->lhs; + struct hlsl_ir_var *var = lhs->var; + unsigned int offset; + + if (!(var_def = copy_propagation_get_var_def(state, var))) + continue; + + if (hlsl_offset_from_deref(lhs, &offset)) + copy_propagation_invalidate_variable_partial(state, var_def, offset, store->writemask); + else + copy_propagation_invalidate_whole_variable(state, var_def); + + break; + } + + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs); + copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs); + + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + + copy_propagation_invalidate_from_block(ctx, state, &loop->body); + + break; + } + + default: + break; + } + } +} + +static void copy_propagation_state_destroy(struct copy_propagation_state *state) +{ + rb_destroy(&state->var_defs, copy_propagation_var_def_destroy, NULL); +} + +static void copy_propagation_state_init(struct hlsl_ctx *ctx, struct copy_propagation_state *state, + struct copy_propagation_state *parent) +{ + rb_init(&state->var_defs, copy_propagation_var_def_compare); + state->parent = parent; +} + static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_propagation_var_def *var_def, unsigned int offset, unsigned int count, unsigned int *swizzle) { @@ -396,7 +487,30 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s if (hlsl_offset_from_deref(lhs, &offset)) copy_propagation_set_value(var_def, offset, store->writemask, store->rhs.node); else - copy_propagation_invalidate_whole_variable(var_def); + copy_propagation_invalidate_whole_variable(state, var_def); +} + +static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct copy_propagation_state *state); + +static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff, + struct copy_propagation_state *state) +{ + struct copy_propagation_state inner_state; + bool progress = false; + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &iff->then_instrs, &inner_state); + copy_propagation_state_destroy(&inner_state); + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &iff->else_instrs, &inner_state); + copy_propagation_state_destroy(&inner_state); + + copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs); + copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs); + + return progress; }
static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -418,8 +532,8 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b break;
case HLSL_IR_IF: - FIXME("Copy propagation doesn't support conditionals yet, leaving.\n"); - return progress; + progress |= copy_propagation_process_if(ctx, hlsl_ir_if(instr), state); + break;
case HLSL_IR_LOOP: FIXME("Copy propagation doesn't support loops yet, leaving.\n"); @@ -438,11 +552,11 @@ static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *bl struct copy_propagation_state state; bool progress;
- rb_init(&state.var_defs, copy_propagation_var_def_compare); + copy_propagation_state_init(ctx, &state, NULL);
progress = copy_propagation_transform_block(ctx, block, &state);
- rb_destroy(&state.var_defs, copy_propagation_var_def_destroy, NULL); + copy_propagation_state_destroy(&state);
return progress; }
Hi,
On 01/12/21 17:14, Matteo Bruni wrote:
changelog: Continue copy propagation after encountering an IF, rework to store the copy_propagation_state structs on the stack and search recursively
I still don't like these changes, they make the code more complicated than it should be, but I'll live with them.
However, I think you're introducing some missed optimizations with this specific patch. For example, take this code:
float2 a; a.x = 1.0; if (condition) { a.y = 2.0; do_something(a.x); }
You would expect a.x replaced with 1.0 in do_something(), but I don't think that's happening in you implementation: inside the conditional a new copy_propagation_var_def is created for variable a, which masks the previous knowledge about a.x being 1.0. This can probably be fixed in copy_propagation_create_var_def in the missing entry case by first doing a lookup on the lower frames and using that result, if it exists, to initialize the new copy_propagation_var_def.
Giovanni.
On 12/3/21 03:28, Giovanni Mascellani wrote:
Hi,
On 01/12/21 17:14, Matteo Bruni wrote:
changelog: Continue copy propagation after encountering an IF, rework to store the copy_propagation_state structs on the stack and search recursively
I still don't like these changes, they make the code more complicated than it should be, but I'll live with them.
However, I think you're introducing some missed optimizations with this specific patch. For example, take this code:
float2 a; a.x = 1.0; if (condition) { Â Â Â a.y = 2.0; Â Â Â do_something(a.x); }
You would expect a.x replaced with 1.0 in do_something(), but I don't think that's happening in you implementation: inside the conditional a new copy_propagation_var_def is created for variable a, which masks the previous knowledge about a.x being 1.0. This can probably be fixed in copy_propagation_create_var_def in the missing entry case by first doing a lookup on the lower frames and using that result, if it exists, to initialize the new copy_propagation_var_def.
Actually, it's worse than that; this patch seems to be incorrectly optimizing the following code:
--
bool b;
float4 main() : sv_target { float2 a; a.x = 1.0; if (b) { a.y = 2.0; a.x += 3; } return float4(a, 0.0, 0.0); }
--
The intermediate IR dump says:
2: bool | b 3: float | 1.00000000e+00 4: | = (a.x @3) 5: | if (@2) { 6: float | 2.00000000e+00 7: | = (a.y @6) 8: float2 | @6.xx 9: float1 | @8.x 10: float | 3.00000000e+00 11: float | + (@9 @10 ) 12: | = (a.x @11) } else { } 13: float2 | a 14: float | 0.00000000e+00 15: float | 0.00000000e+00 16: | = (<constructor-0>.xy @13) 17: | = (<constructor-0>.z @14) 18: | = (<constructor-0>.w @15) 19: float4 | <constructor-0> 20: | return 21: | = (<output-sv_target0> @19)
Note instruction 8 here, which is probably supposed to be @3.xx rather than @6.xx.
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Continue copy propagation after encountering a LOOP, rework for the copy_propagation_state change.
libs/vkd3d-shader/hlsl_codegen.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index cbe546c3..2ef51f78 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -513,6 +513,21 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if return progress; }
+static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_loop *loop, + struct copy_propagation_state *state) +{ + struct copy_propagation_state inner_state; + bool progress = false; + + copy_propagation_invalidate_from_block(ctx, state, &loop->body); + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &loop->body, &inner_state); + copy_propagation_state_destroy(&inner_state); + + return progress; +} + static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct copy_propagation_state *state) { @@ -536,8 +551,8 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b break;
case HLSL_IR_LOOP: - FIXME("Copy propagation doesn't support loops yet, leaving.\n"); - return progress; + progress |= copy_propagation_process_loop(ctx, hlsl_ir_loop(instr), state); + break;
default: break;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 01/12/21 17:14, Matteo Bruni wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Continue copy propagation after encountering a LOOP, rework for the copy_propagation_state change.
libs/vkd3d-shader/hlsl_codegen.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index cbe546c3..2ef51f78 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -513,6 +513,21 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if return progress; }
+static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_loop *loop,
struct copy_propagation_state *state)
+{
- struct copy_propagation_state inner_state;
- bool progress = false;
- copy_propagation_invalidate_from_block(ctx, state, &loop->body);
- copy_propagation_state_init(ctx, &inner_state, state);
- progress |= copy_propagation_transform_block(ctx, &loop->body, &inner_state);
- copy_propagation_state_destroy(&inner_state);
- return progress;
+}
- static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct copy_propagation_state *state) {
@@ -536,8 +551,8 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b break;
case HLSL_IR_LOOP:
FIXME("Copy propagation doesn't support loops yet, leaving.\n");
return progress;
progress |= copy_propagation_process_loop(ctx, hlsl_ir_loop(instr), state);
break; default: break;
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Try constant propagation first.
libs/vkd3d-shader/hlsl_codegen.c | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2ef51f78..6773ab81 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -438,6 +438,48 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_pro return node; }
+static struct hlsl_ir_node *copy_propagation_compute_constant(struct hlsl_ctx *ctx, + struct copy_propagation_var_def *variable, unsigned int offset, unsigned int count, + const struct vkd3d_shader_location *loc) +{ + enum hlsl_base_type type = HLSL_TYPE_VOID; + struct hlsl_ir_constant *constant = NULL; + unsigned int i; + + assert(offset + count <= variable->var->data_type->reg_size); + + for (i = 0; i < count; ++i) + { + struct hlsl_ir_node *store_node = variable->values[offset + i].node; + enum hlsl_base_type store_type; + + if (!store_node) + return NULL; + if (store_node->type != HLSL_IR_CONSTANT) + return NULL; + + store_type = store_node->data_type->base_type; + + if (type == HLSL_TYPE_VOID) + type = store_type; + else if (type != store_type) + return NULL; + } + + if (!(constant = hlsl_new_uint_constant(ctx, 0, *loc))) + return NULL; + constant->node.data_type = hlsl_get_vector_type(ctx, type, count); + + for (i = 0; i < count; ++i) + { + struct hlsl_ir_node *store_node = variable->values[offset + i].node; + + constant->value[i] = hlsl_ir_constant(store_node)->value[variable->values[offset + i].component]; + } + + return &constant->node; +} + static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, struct copy_propagation_state *state) { @@ -458,6 +500,15 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l if (!(var_def = copy_propagation_get_var_def(state, var))) return false;
+ if ((new_node = copy_propagation_compute_constant(ctx, var_def, offset, type->dimx, &load->node.loc))) + { + TRACE("Load from %s[%d-%d] reconstructed as constant value.\n", + var->name, offset, offset + type->dimx); + list_add_before(&node->entry, &new_node->entry); + replace_node(node, new_node); + return true; + } + if (!(new_node = copy_propagation_compute_replacement(var_def, offset, type->dimx, &swizzle))) { TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
On 12/1/21 10:14, Matteo Bruni wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Try constant propagation first.
libs/vkd3d-shader/hlsl_codegen.c | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
I'm afraid I don't understand; what exactly is this patch doing that 1/17 doesn't?
On Wed, Dec 1, 2021 at 5:46 PM Zebediah Figura zfigura@codeweavers.com wrote:
On 12/1/21 10:14, Matteo Bruni wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Try constant propagation first.
libs/vkd3d-shader/hlsl_codegen.c | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
I'm afraid I don't understand; what exactly is this patch doing that 1/17 doesn't?
IIRC this patch gets rid of unnecessary copies from an immediate to a temporary variable. I already forgot the details but I'm pretty sure that it did something...
I guess I'll have another look at some point, it's possible that it's just hiding a bug or something like that.
Hi,
On 01/12/21 17:55, Matteo Bruni wrote:
IIRC this patch gets rid of unnecessary copies from an immediate to a temporary variable. I already forgot the details but I'm pretty sure that it did something...
I already replied privately, but for the sake of having a publicly archived reference, this patch converts this:
trace:hlsl_dump_function: 2: float | 1.00000000e+00 trace:hlsl_dump_function: 3: float | 2.00000000e+00 trace:hlsl_dump_function: 4: float | 3.00000000e+00 trace:hlsl_dump_function: 5: float | 4.00000000e+00 trace:hlsl_dump_function: 6: | = (<constructor-0>.x @2) trace:hlsl_dump_function: 7: | = (<constructor-0>.y @3) trace:hlsl_dump_function: 8: | = (<constructor-0>.z @4) trace:hlsl_dump_function: 9: | = (<constructor-0>.w @5) trace:hlsl_dump_function: 10: float4 | <constructor-0> trace:hlsl_dump_function: 11: | return
to this:
trace:hlsl_dump_function: 2: float4 | {1.00000000e+00 2.00000000e+00 3.00000000e+00 4.00000000e+00 } trace:hlsl_dump_function: 3: | return
It is not something 1/17 can (or should) be able to do. There might be a better way to do this with more generality, but this is here right now, so I think it makes sense to have it in master.
Giovanni.
On 12/2/21 09:02, Giovanni Mascellani wrote:
Hi,
On 01/12/21 17:55, Matteo Bruni wrote:
IIRC this patch gets rid of unnecessary copies from an immediate to a temporary variable. I already forgot the details but I'm pretty sure that it did something...
I already replied privately, but for the sake of having a publicly archived reference, this patch converts this:
trace:hlsl_dump_function:Â Â Â 2:Â Â Â Â Â float | 1.00000000e+00 trace:hlsl_dump_function:Â Â Â 3:Â Â Â Â Â float | 2.00000000e+00 trace:hlsl_dump_function:Â Â Â 4:Â Â Â Â Â float | 3.00000000e+00 trace:hlsl_dump_function:Â Â Â 5:Â Â Â Â Â float | 4.00000000e+00 trace:hlsl_dump_function:Â Â Â 6:Â Â Â Â Â Â Â Â Â Â Â | = (<constructor-0>.x @2) trace:hlsl_dump_function:Â Â Â 7:Â Â Â Â Â Â Â Â Â Â Â | = (<constructor-0>.y @3) trace:hlsl_dump_function:Â Â Â 8:Â Â Â Â Â Â Â Â Â Â Â | = (<constructor-0>.z @4) trace:hlsl_dump_function:Â Â Â 9:Â Â Â Â Â Â Â Â Â Â Â | = (<constructor-0>.w @5) trace:hlsl_dump_function:Â Â 10:Â Â Â Â float4 | <constructor-0> trace:hlsl_dump_function:Â Â 11:Â Â Â Â Â Â Â Â Â Â Â | return
to this:
trace:hlsl_dump_function:Â Â Â 2:Â Â Â Â float4 | {1.00000000e+00 2.00000000e+00 3.00000000e+00 4.00000000e+00 } trace:hlsl_dump_function:Â Â Â 3:Â Â Â Â Â Â Â Â Â Â Â | return
It is not something 1/17 can (or should) be able to do. There might be a better way to do this with more generality, but this is here right now, so I think it makes sense to have it in master.
Right. And for the sake of further reference, my argument is that we should have a generic coalescing/vectorization pass, which would convert
2: 1.0 3. 1.0 4: = (var.x @2) 5: = (var.y @3)
into
2: (1.0, 1.0) 3: = (var.xy @2)
without depending on there being a following load, whereupon the existing copy-prop pass should be able to handle the rest of the optimization.
If this pass is going to be hard to write, I'm fine enough with using this patch as a temporary solution. It's not clear to me that the pass *is* hard to write, but it probably won't make it into 1.3 if that's going to be released soon. Of course, it's also not clear to me that we really *need* a temporary solution...
Hi,
On 02/12/21 17:17, Zebediah Figura wrote:
If this pass is going to be hard to write, I'm fine enough with using this patch as a temporary solution. It's not clear to me that the pass *is* hard to write, but it probably won't make it into 1.3 if that's going to be released soon. Of course, it's also not clear to me that we really *need* a temporary solution...
For sure we don't need it, but as much as we probably don't need most of the other optimization passes we have, including copy propagation as a whole (except for the bit about uniform objects). Whatever code we compile to, it will eventually be re-compiled by a few other compilers, at least one of which is probably better than ours and, more importantly, knows about which hardware it is compiling for.
To me, optimization passes are currently mostly helpful to produce code that can reasonably read by a human to verify that compilation is correct. To this end, I think 4/17 is useful (as it will be a vectorization pass, as soon as it will exist).
Giovanni.
On 12/3/21 02:52, Giovanni Mascellani wrote:
Hi,
On 02/12/21 17:17, Zebediah Figura wrote:
If this pass is going to be hard to write, I'm fine enough with using this patch as a temporary solution. It's not clear to me that the pass *is* hard to write, but it probably won't make it into 1.3 if that's going to be released soon. Of course, it's also not clear to me that we really *need* a temporary solution...
For sure we don't need it, but as much as we probably don't need most of the other optimization passes we have, including copy propagation as a whole (except for the bit about uniform objects). Whatever code we compile to, it will eventually be re-compiled by a few other compilers, at least one of which is probably better than ours and, more importantly, knows about which hardware it is compiling for.
To me, optimization passes are currently mostly helpful to produce code that can reasonably read by a human to verify that compilation is correct. To this end, I think 4/17 is useful (as it will be a vectorization pass, as soon as it will exist).
Well, we do sort of need copy-propagation so that we can deal with object variables (including e.g. object variables returned from a function, which I've seen in actual shaders). We can't translate those load/store instrs to actual DXBC, because there's no such thing as an object-typed temp.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com ---
On 01/12/21 17:14, Matteo Bruni wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Try constant propagation first.
No objections here, but any particular reason?
@@ -458,6 +500,15 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l if (!(var_def = copy_propagation_get_var_def(state, var))) return false;
- if ((new_node = copy_propagation_compute_constant(ctx, var_def, offset, type->dimx, &load->node.loc)))
- {
TRACE("Load from %s[%d-%d] reconstructed as constant value.\n",
var->name, offset, offset + type->dimx);
list_add_before(&node->entry, &new_node->entry);
replace_node(node, new_node);
return true;
- }
if (!(new_node = copy_propagation_compute_replacement(var_def, offset, type->dimx, &swizzle))) { TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
I think the code would be more readable it it was like:
--- if (c_p_compute_constant()) { ... return true; }
if (c_p_compute_replacement()) { ... return true; }
TRACE("failure, no optimization for you today, rotfl lol\n"); return false; ---
But I can live with that too. :-)
Giovanni.
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Fix typo in the call to sm4_register_from_deref() for the sampler argument.
libs/vkd3d-shader/hlsl_sm4.c | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index c0c26f80..1c0fea53 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -753,7 +753,7 @@ struct sm4_instruction struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type; unsigned int swizzle; - } srcs[2]; + } srcs[3]; unsigned int src_count;
uint32_t idx[2]; @@ -776,6 +776,16 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL; } + else if (data_type->type == HLSL_CLASS_OBJECT && data_type->base_type == HLSL_TYPE_SAMPLER) + { + reg->type = VKD3D_SM4_RT_SAMPLER; + reg->dim = VKD3D_SM4_DIMENSION_NONE; + if (swizzle_type) + *swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + reg->idx[0] = var->reg.id; + reg->idx_count = 1; + *writemask = VKD3DSP_WRITEMASK_ALL; + } else { unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref) + var->buffer_offset; @@ -1238,6 +1248,34 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf write_sm4_instruction(buffer, &instr); }
+static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, + const struct hlsl_deref *resource, const struct hlsl_deref *sampler, const struct hlsl_ir_node *coords) +{ + struct sm4_instruction instr; + unsigned int writemask; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_SAMPLE; + + sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst); + instr.dst_count = 1; + + sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, coords); + instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask); + + sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask, + &instr.srcs[1].swizzle_type, resource, resource_type); + instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + + sm4_register_from_deref(ctx, &instr.srcs[2].reg, &writemask, + &instr.srcs[2].swizzle_type, sampler, sampler->var->data_type); + + instr.src_count = 3; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) { @@ -1516,6 +1554,21 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, const struct hlsl_type *resource_type = load->resource.var->data_type; const struct hlsl_ir_node *coords = load->coords.node;
+ if (load->sampler.var) + { + const struct hlsl_type *sampler_type = load->sampler.var->data_type; + + assert(sampler_type->type == HLSL_CLASS_OBJECT); + assert(sampler_type->base_type == HLSL_TYPE_SAMPLER); + assert(sampler_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC); + + if (!load->sampler.var->is_uniform) + { + hlsl_fixme(ctx, load->node.loc, "Sample using non-uniform sampler variable."); + return; + } + } + if (!load->resource.var->is_uniform) { hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable."); @@ -1529,7 +1582,9 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, break;
case HLSL_RESOURCE_SAMPLE: - hlsl_fixme(ctx, load->node.loc, "Resource sample instruction."); + if (!load->sampler.var) + hlsl_fixme(ctx, load->node.loc, "SM4 combined sample expression."); + write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords); break; } }
Signed-off-by: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 01/12/21 17:14, Matteo Bruni wrote:
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Fix typo in the call to sm4_register_from_deref() for the sampler argument.
libs/vkd3d-shader/hlsl_sm4.c | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index c0c26f80..1c0fea53 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -753,7 +753,7 @@ struct sm4_instruction struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type; unsigned int swizzle;
- } srcs[2];
} srcs[3]; unsigned int src_count;
uint32_t idx[2];
@@ -776,6 +776,16 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL; }
else if (data_type->type == HLSL_CLASS_OBJECT && data_type->base_type == HLSL_TYPE_SAMPLER)
{
reg->type = VKD3D_SM4_RT_SAMPLER;
reg->dim = VKD3D_SM4_DIMENSION_NONE;
if (swizzle_type)
*swizzle_type = VKD3D_SM4_SWIZZLE_NONE;
reg->idx[0] = var->reg.id;
reg->idx_count = 1;
*writemask = VKD3DSP_WRITEMASK_ALL;
} else { unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref) + var->buffer_offset;
@@ -1238,6 +1248,34 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf write_sm4_instruction(buffer, &instr); }
+static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst,
const struct hlsl_deref *resource, const struct hlsl_deref *sampler, const struct hlsl_ir_node *coords)
+{
- struct sm4_instruction instr;
- unsigned int writemask;
- memset(&instr, 0, sizeof(instr));
- instr.opcode = VKD3D_SM4_OP_SAMPLE;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst);
- instr.dst_count = 1;
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, coords);
- instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask);
- sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask,
&instr.srcs[1].swizzle_type, resource, resource_type);
- instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
- sm4_register_from_deref(ctx, &instr.srcs[2].reg, &writemask,
&instr.srcs[2].swizzle_type, sampler, sampler->var->data_type);
- instr.src_count = 3;
- write_sm4_instruction(buffer, &instr);
+}
- static void write_sm4_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) {
@@ -1516,6 +1554,21 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, const struct hlsl_type *resource_type = load->resource.var->data_type; const struct hlsl_ir_node *coords = load->coords.node;
- if (load->sampler.var)
- {
const struct hlsl_type *sampler_type = load->sampler.var->data_type;
assert(sampler_type->type == HLSL_CLASS_OBJECT);
assert(sampler_type->base_type == HLSL_TYPE_SAMPLER);
assert(sampler_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC);
if (!load->sampler.var->is_uniform)
{
hlsl_fixme(ctx, load->node.loc, "Sample using non-uniform sampler variable.");
return;
}
- }
if (!load->resource.var->is_uniform) { hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable.");
@@ -1529,7 +1582,9 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, break;
case HLSL_RESOURCE_SAMPLE:
hlsl_fixme(ctx, load->node.loc, "Resource sample instruction.");
if (!load->sampler.var)
hlsl_fixme(ctx, load->node.loc, "SM4 combined sample expression.");
}write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords); break; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Create a new cast instruction instead of reusing the existing one. Also I added a comment to clarify why the cast is preserved e.g. instead of skipping the cast instruction and swizzling the cast operand directly.
Makefile.am | 1 - libs/vkd3d-shader/hlsl_codegen.c | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am index be3d8ec1..4010533a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,7 +290,6 @@ XFAIL_TESTS = \ tests/conditional.shader_test \ tests/hlsl-array-dimension.shader_test \ tests/hlsl-bool-cast.shader_test \ - tests/hlsl-comma.shader_test \ tests/hlsl-cross.shader_test \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 6773ab81..3cc41d4e 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -237,6 +237,43 @@ static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) hlsl_free_instr(old); }
+/* Lower casts from vec1 to vecN to swizzles. */ +static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_scalar_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) + return false; + cast = hlsl_ir_expr(instr); + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + + if (cast->op == HLSL_OP1_CAST + && src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR + && src_type->dimx == 1) + { + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_expr *new_cast; + + dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->base_type); + /* We need to preserve the cast since it might be doing more than just + * turning the scalar into a vector. */ + if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) + return false; + list_add_after(&cast->node.entry, &new_cast->node.entry); + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->dimx, &new_cast->node, &cast->node.loc))) + return false; + list_add_after(&new_cast->node.entry, &swizzle->node.entry); + + replace_node(&cast->node, &swizzle->node); + return true; + } + + return false; +} + struct copy_propagation_value { struct hlsl_ir_node *node; @@ -1804,6 +1841,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun append_output_var_copy(ctx, &body->instrs, entry_func->return_var); }
+ transform_ir(ctx, lower_broadcasts, body, NULL); while (transform_ir(ctx, fold_redundant_casts, body, NULL)); do {
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Though with a few comments...
On 01/12/21 17:14, Matteo Bruni wrote:
- if (instr->type != HLSL_IR_EXPR)
return false;
- cast = hlsl_ir_expr(instr);
- src_type = cast->operands[0].node->data_type;
- dst_type = cast->node.data_type;
Here operands[0].node is assumed to be valid before we know the operation is checked to be OP1_CAST. I know that we don't have nullary operators and I can't see why we might eventually have one, but I still don't like the idea.
- if (cast->op == HLSL_OP1_CAST
&& src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR
&& src_type->dimx == 1)
I don't like how this is formatted. I would either put each conjoint on a dedicated line, or put two in one line and two in another. This 1-2-1 structure makes it more difficult to parse to the eye, at least to my eye.
Thanks, Giovanni.
On 12/2/21 09:26, Giovanni Mascellani wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Though with a few comments...
On 01/12/21 17:14, Matteo Bruni wrote:
+Â Â Â if (instr->type != HLSL_IR_EXPR) +Â Â Â Â Â Â Â return false; +Â Â Â cast = hlsl_ir_expr(instr); +Â Â Â src_type = cast->operands[0].node->data_type; +Â Â Â dst_type = cast->node.data_type;
Here operands[0].node is assumed to be valid before we know the operation is checked to be OP1_CAST. I know that we don't have nullary operators and I can't see why we might eventually have one, but I still don't like the idea.
Yes, I suppose I would agree.
+Â Â Â if (cast->op == HLSL_OP1_CAST +Â Â Â Â Â Â Â Â Â Â Â && src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR +Â Â Â Â Â Â Â Â Â Â Â && src_type->dimx == 1)
I don't like how this is formatted. I would either put each conjoint on a dedicated line, or put two in one line and two in another. This 1-2-1 structure makes it more difficult to parse to the eye, at least to my eye.
The mental logic is that it compares "op", then "type" (for both sources), then "dimx". I don't feel strongly about it, though.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Create a new cast instruction instead of reusing the existing one.
Makefile.am | 1 - libs/vkd3d-shader/hlsl_codegen.c | 37 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 15 ++++++------- 3 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 4010533a..88bdc0ee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,7 +290,6 @@ XFAIL_TESTS = \ tests/conditional.shader_test \ tests/hlsl-array-dimension.shader_test \ tests/hlsl-bool-cast.shader_test \ - tests/hlsl-cross.shader_test \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \ diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 3cc41d4e..64450c76 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -796,6 +796,42 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_vector_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) + return false; + cast = hlsl_ir_expr(instr); + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + + if (cast->op == HLSL_OP1_CAST + && src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR + && dst_type->dimx < src_type->dimx) + { + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_expr *new_cast; + + dst_vector_type = hlsl_get_vector_type(ctx, dst_type->base_type, src_type->dimx); + /* We need to preserve the cast since it might be doing more than just + * narrowing the vector. */ + if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) + return false; + list_add_after(&cast->node.entry, &new_cast->node.entry); + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->dimx, &new_cast->node, &cast->node.loc))) + return false; + list_add_after(&new_cast->node.entry, &swizzle->node.entry); + + replace_node(&cast->node, &swizzle->node); + return true; + } + + return false; +} + static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -1849,6 +1885,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun progress |= transform_ir(ctx, split_struct_copies, body, NULL); } while (progress); + transform_ir(ctx, lower_narrowing_casts, body, NULL); do { progress = transform_ir(ctx, fold_constants, body, NULL); diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 1c0fea53..a75abbc0 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1298,9 +1298,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
- /* Narrowing casts need to be lowered. */ - if (src_type->dimx != expr->node.data_type->dimx) - hlsl_fixme(ctx, expr->node.loc, "Narrowing cast.\n"); + /* Narrowing casts were already lowered. */ + assert(src_type->dimx == expr->node.data_type->dimx);
switch (src_type->base_type) { @@ -1388,9 +1387,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
- /* Narrowing casts need to be lowered. */ - if (src_type->dimx != expr->node.data_type->dimx) - hlsl_fixme(ctx, expr->node.loc, "Narrowing cast."); + /* Narrowing casts were already lowered. */ + assert(src_type->dimx == expr->node.data_type->dimx);
switch (src_type->base_type) { @@ -1433,9 +1431,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
- /* Narrowing casts need to be lowered. */ - if (src_type->dimx != expr->node.data_type->dimx) - hlsl_fixme(ctx, expr->node.loc, "SM4 narrowing cast.\n"); + /* Narrowing casts were already lowered. */ + assert(src_type->dimx == expr->node.data_type->dimx);
switch (src_type->base_type) {
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- With the same comments as 6/17.
On 01/12/21 17:14, Matteo Bruni wrote:
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Create a new cast instruction instead of reusing the existing one.
Makefile.am | 1 - libs/vkd3d-shader/hlsl_codegen.c | 37 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 15 ++++++------- 3 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 4010533a..88bdc0ee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,7 +290,6 @@ XFAIL_TESTS = \ tests/conditional.shader_test \ tests/hlsl-array-dimension.shader_test \ tests/hlsl-bool-cast.shader_test \
- tests/hlsl-cross.shader_test \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 3cc41d4e..64450c76 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -796,6 +796,42 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{
- const struct hlsl_type *src_type, *dst_type;
- struct hlsl_type *dst_vector_type;
- struct hlsl_ir_expr *cast;
- if (instr->type != HLSL_IR_EXPR)
return false;
- cast = hlsl_ir_expr(instr);
- src_type = cast->operands[0].node->data_type;
- dst_type = cast->node.data_type;
- if (cast->op == HLSL_OP1_CAST
&& src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR
&& dst_type->dimx < src_type->dimx)
- {
struct hlsl_ir_swizzle *swizzle;
struct hlsl_ir_expr *new_cast;
dst_vector_type = hlsl_get_vector_type(ctx, dst_type->base_type, src_type->dimx);
/* We need to preserve the cast since it might be doing more than just
* narrowing the vector. */
if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc)))
return false;
list_add_after(&cast->node.entry, &new_cast->node.entry);
if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->dimx, &new_cast->node, &cast->node.loc)))
return false;
list_add_after(&new_cast->node.entry, &swizzle->node.entry);
replace_node(&cast->node, &swizzle->node);
return true;
- }
- return false;
+}
- static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res;
@@ -1849,6 +1885,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun progress |= transform_ir(ctx, split_struct_copies, body, NULL); } while (progress);
- transform_ir(ctx, lower_narrowing_casts, body, NULL); do { progress = transform_ir(ctx, fold_constants, body, NULL);
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 1c0fea53..a75abbc0 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1298,9 +1298,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
/* Narrowing casts need to be lowered. */
if (src_type->dimx != expr->node.data_type->dimx)
hlsl_fixme(ctx, expr->node.loc, "Narrowing cast.\n");
/* Narrowing casts were already lowered. */
assert(src_type->dimx == expr->node.data_type->dimx); switch (src_type->base_type) {
@@ -1388,9 +1387,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
/* Narrowing casts need to be lowered. */
if (src_type->dimx != expr->node.data_type->dimx)
hlsl_fixme(ctx, expr->node.loc, "Narrowing cast.");
/* Narrowing casts were already lowered. */
assert(src_type->dimx == expr->node.data_type->dimx); switch (src_type->base_type) {
@@ -1433,9 +1431,8 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, { const struct hlsl_type *src_type = arg1->data_type;
/* Narrowing casts need to be lowered. */
if (src_type->dimx != expr->node.data_type->dimx)
hlsl_fixme(ctx, expr->node.loc, "SM4 narrowing cast.\n");
/* Narrowing casts were already lowered. */
assert(src_type->dimx == expr->node.data_type->dimx); switch (src_type->base_type) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 18 +-- libs/vkd3d-shader/hlsl.h | 8 +- libs/vkd3d-shader/hlsl.l | 2 +- libs/vkd3d-shader/hlsl.y | 194 +++++++++++++++---------------- libs/vkd3d-shader/hlsl_codegen.c | 26 ++--- libs/vkd3d-shader/hlsl_sm1.c | 8 +- libs/vkd3d-shader/hlsl_sm4.c | 32 ++--- 7 files changed, 144 insertions(+), 144 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8895f5bc..fe0b44d8 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -22,40 +22,40 @@ #include "hlsl.h" #include <stdio.h>
-void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_log_level level, const char *fmt, ...) { va_list args;
va_start(args, fmt); - vkd3d_shader_vnote(ctx->message_context, &loc, level, fmt, args); + vkd3d_shader_vnote(ctx->message_context, loc, level, fmt, args); va_end(args); }
-void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) { va_list args;
va_start(args, fmt); - vkd3d_shader_verror(ctx->message_context, &loc, error, fmt, args); + vkd3d_shader_verror(ctx->message_context, loc, error, fmt, args); va_end(args);
if (!ctx->result) ctx->result = VKD3D_ERROR_INVALID_SHADER; }
-void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) { va_list args;
va_start(args, fmt); - vkd3d_shader_vwarning(ctx->message_context, &loc, error, fmt, args); + vkd3d_shader_vwarning(ctx->message_context, loc, error, fmt, args); va_end(args); }
-void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, const char *fmt, ...) +void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, const char *fmt, ...) { struct vkd3d_string_buffer *string; va_list args; @@ -64,7 +64,7 @@ void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, co string = hlsl_get_string_buffer(ctx); vkd3d_string_buffer_printf(string, "Aborting due to not yet implemented feature: "); vkd3d_string_buffer_vprintf(string, fmt, args); - vkd3d_shader_error(ctx->message_context, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer); + vkd3d_shader_error(ctx->message_context, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer); hlsl_release_string_buffer(ctx, string); va_end(args);
@@ -1960,7 +1960,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d { const struct vkd3d_shader_location loc = {.source_name = compile_info->source_name};
- hlsl_error(&ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Entry point "%s" is not defined.", entry_point); hlsl_ctx_cleanup(&ctx); return VKD3D_ERROR_INVALID_SHADER; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index eb11b4ab..ffc228d8 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -728,13 +728,13 @@ struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, const struct vkd3d_shader_location loc);
-void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); -void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4); -void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); -void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, +void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_log_level level, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
void hlsl_push_scope(struct hlsl_ctx *ctx); diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index caf8fe8f..e9281ec3 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -65,7 +65,7 @@ ANY (.) {RESERVED4} { struct hlsl_ctx *ctx = yyget_extra(yyscanner);
- hlsl_error(ctx, *yylloc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + hlsl_error(ctx, yylloc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Reserved keyword "%s" used.", yytext); }
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ff35c09e..97dc9891 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -111,7 +111,7 @@ int yylex(HLSL_YYSTYPE *yylval_param, HLSL_YYLTYPE *yylloc_param, void *yyscanne
static void yyerror(YYLTYPE *loc, void *scanner, struct hlsl_ctx *ctx, const char *s) { - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "%s", s); + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "%s", s); }
static struct hlsl_ir_node *node_from_list(struct list *list) @@ -137,7 +137,7 @@ static void destroy_instr_list(struct list *list) static void check_invalid_matrix_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, struct vkd3d_shader_location loc) { if (modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "'row_major' and 'column_major' modifiers are only allowed for matrices."); }
@@ -281,7 +281,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct src_string = hlsl_type_to_string(ctx, src_type); dst_string = hlsl_type_to_string(ctx, dst_type); if (src_string && dst_string) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); hlsl_release_string_buffer(ctx, src_string); hlsl_release_string_buffer(ctx, dst_string); @@ -289,7 +289,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct }
if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) - hlsl_warning(ctx, *loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix");
if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) @@ -305,14 +305,14 @@ static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, con struct vkd3d_string_buffer *string;
if ((string = hlsl_modifiers_to_string(ctx, mod))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifier '%s' was already specified.", string->buffer); hlsl_release_string_buffer(ctx, string); return modifiers; } if ((mod & HLSL_MODIFIERS_MAJORITY_MASK) && (modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "'row_major' and 'column_major' modifiers are mutually exclusive."); return modifiers; } @@ -516,7 +516,7 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs } else if (ctx->cur_function->return_var) { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Non-void function must return a value."); + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Non-void function must return a value."); return NULL; }
@@ -601,9 +601,9 @@ static struct hlsl_ir_load *add_array_load(struct hlsl_ctx *ctx, struct list *in else { if (expr_type->type == HLSL_CLASS_SCALAR) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed."); + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed."); else - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Expression cannot be array-indexed."); + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Expression cannot be array-indexed."); return NULL; }
@@ -661,7 +661,7 @@ static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_ *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK;
if ((new_type->modifiers & HLSL_MODIFIER_ROW_MAJOR) && (new_type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "'row_major' and 'column_major' modifiers are mutually exclusive.");
return new_type; @@ -696,7 +696,7 @@ static struct list *gen_struct_fields(struct hlsl_ctx *ctx, struct hlsl_type *ty field->semantic = v->semantic; if (v->initializer.args_count) { - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); free_parse_initializer(&v->initializer); } list_add_tail(list, &field->entry); @@ -739,12 +739,12 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type
if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)) - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "'row_major' and 'column_major' modifiers are mutually exclusive.");
ret = hlsl_scope_add_type(ctx->cur_scope, type); if (!ret) - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Type '%s' is already defined.", v->name); vkd3d_free(v); } @@ -761,7 +761,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Parameter '%s' is declared as both "out" and "uniform".", param->name);
if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ¶m->reg_reservation))) @@ -928,7 +928,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, t1))) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); hlsl_release_string_buffer(ctx, string); return false; @@ -939,7 +939,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, t2))) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); hlsl_release_string_buffer(ctx, string); return false; @@ -951,7 +951,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct struct vkd3d_string_buffer *t2_string = hlsl_type_to_string(ctx, t2);
if (t1_string && t2_string) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expression data types "%s" and "%s" are incompatible.", t1_string->buffer, t2_string->buffer); hlsl_release_string_buffer(ctx, t1_string); @@ -1191,7 +1191,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) { - hlsl_fixme(ctx, lhs->loc, "Cast on the LHS."); + hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS."); vkd3d_free(store); return NULL; } @@ -1201,11 +1201,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in unsigned int width, s = swizzle->swizzle;
if (lhs->data_type->type == HLSL_CLASS_MATRIX) - hlsl_fixme(ctx, lhs->loc, "Matrix assignment with a writemask."); + hlsl_fixme(ctx, &lhs->loc, "Matrix assignment with a writemask.");
if (!invert_swizzle(&s, &writemask, &width)) { - hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); vkd3d_free(store); return NULL; } @@ -1222,7 +1222,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in } else { - hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); vkd3d_free(store); return NULL; } @@ -1251,7 +1251,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem struct hlsl_ir_constant *one;
if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in");
if (!(one = hlsl_new_uint_constant(ctx, 1, loc))) @@ -1286,7 +1286,7 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru
if (initializer_size(initializer) != hlsl_type_component_count(type)) { - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Expected %u components in initializer, but got %u.", hlsl_type_component_count(type), initializer_size(initializer)); free_parse_initializer(initializer); @@ -1317,7 +1317,7 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru } else { - hlsl_fixme(ctx, node->loc, "Implicit cast in structure initializer."); + hlsl_fixme(ctx, &node->loc, "Implicit cast in structure initializer."); } }
@@ -1381,7 +1381,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t local = false;
if ((modifiers & HLSL_STORAGE_UNIFORM) && (modifiers & HLSL_STORAGE_STATIC)) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Variable '%s' is declared as both "uniform" and "static".", var->name);
/* Mark it as uniform. We need to do this here since synthetic @@ -1392,9 +1392,9 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
if ((func = hlsl_get_func_decl(ctx, var->name))) { - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "'%s' is already defined as a function.", var->name); - hlsl_note(ctx, func->loc, VKD3D_SHADER_LOG_ERROR, + hlsl_note(ctx, &func->loc, VKD3D_SHADER_LOG_ERROR, "'%s' was previously defined here.", var->name); } } @@ -1408,19 +1408,19 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t struct vkd3d_string_buffer *string;
if ((string = hlsl_modifiers_to_string(ctx, modifiers & invalid))) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers '%s' are not allowed on local variables.", string->buffer); hlsl_release_string_buffer(ctx, string); } if (var->semantic.name) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on local variables."); }
if ((type->modifiers & HLSL_MODIFIER_CONST) && !v->initializer.args_count && !(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_UNIFORM))) { - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, "Const variable "%s" is missing an initializer.", var->name); hlsl_free_var(var); vkd3d_free(v); @@ -1431,9 +1431,9 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t { struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name);
- hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Variable "%s" was already declared in this scope.", var->name); - hlsl_note(ctx, old->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", old->name); + hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", old->name); hlsl_free_var(var); vkd3d_free(v); continue; @@ -1449,7 +1449,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t { if (size < type->dimx * type->dimy) { - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Expected %u components in numeric initializer, but got %u.", type->dimx * type->dimy, size); free_parse_initializer(&v->initializer); @@ -1460,7 +1460,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY) && hlsl_type_component_count(type) != size) { - hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Expected %u components in initializer, but got %u.", hlsl_type_component_count(type), size); free_parse_initializer(&v->initializer); vkd3d_free(v); @@ -1482,14 +1482,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t } if (v->arrays.count) { - hlsl_fixme(ctx, v->loc, "Array initializer."); + hlsl_fixme(ctx, &v->loc, "Array initializer."); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; } if (v->initializer.args_count > 1) { - hlsl_fixme(ctx, v->loc, "Complex initializer."); + hlsl_fixme(ctx, &v->loc, "Complex initializer."); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; @@ -1711,7 +1711,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
if ((decl = find_function_call(ctx, name, params))) { - hlsl_fixme(ctx, loc, "Call to user-defined function "%s".", name); + hlsl_fixme(ctx, &loc, "Call to user-defined function "%s".", name); free_parse_initializer(params); return NULL; } @@ -1720,7 +1720,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, { if (intrinsic->param_count >= 0 && params->args_count != intrinsic->param_count) { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Wrong number of arguments to function '%s': expected %u, but got %u.\n", name, intrinsic->param_count, params->args_count); free_parse_initializer(params); @@ -1738,7 +1738,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, params->args[i]->data_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Wrong type for argument %u of '%s': expected a numeric type, but got '%s'.\n", i + 1, name, string->buffer); hlsl_release_string_buffer(ctx, string); @@ -1756,7 +1756,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, } else { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function "%s" is not defined.", name); + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function "%s" is not defined.", name); free_parse_initializer(params); return NULL; } @@ -1775,7 +1775,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type char name[23];
if (type->type == HLSL_CLASS_MATRIX) - hlsl_fixme(ctx, loc, "Matrix constructor."); + hlsl_fixme(ctx, &loc, "Matrix constructor.");
sprintf(name, "<constructor-%x>", counter++); if (!(var = hlsl_new_synthetic_var(ctx, name, type, loc))) @@ -1791,7 +1791,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, arg->data_type))) - hlsl_error(ctx, arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Invalid type %s for constructor argument.", string->buffer); hlsl_release_string_buffer(ctx, string); continue; @@ -1836,7 +1836,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Type '%s' does not have methods.", string->buffer); hlsl_release_string_buffer(ctx, string); return false; @@ -1853,7 +1853,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
if (params->args_count < 1 || params->args_count > 3) { - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Wrong number of arguments to method 'Load': expected 1, 2, or 3, but got %u.", params->args_count); return false; } @@ -1881,7 +1881,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
if (params->args_count != 2 && params->args_count != 3) { - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Wrong number of arguments to method 'Sample': expected 2 or 3, but got %u.", params->args_count); return false; } @@ -1895,7 +1895,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); hlsl_release_string_buffer(ctx, string); return false; @@ -1920,7 +1920,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Method '%s' is not defined on type '%s'.", name, string->buffer); hlsl_release_string_buffer(ctx, string); return false; @@ -2162,16 +2162,16 @@ hlsl_prog: { if (decl->has_body && $2.decl->has_body) { - hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &$2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function "%s" is already defined.", $2.name); - hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously defined here.", $2.name); + hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously defined here.", $2.name); YYABORT; } else if (!hlsl_types_are_equal(decl->return_type, $2.decl->return_type)) { - hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &$2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function "%s" was already declared with a different return type.", $2.name); - hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", $2.name); + hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", $2.name); YYABORT; } } @@ -2182,7 +2182,7 @@ hlsl_prog: | hlsl_prog declaration_statement { if (!list_empty($2)) - hlsl_fixme(ctx, @2, "Uniform initializer."); + hlsl_fixme(ctx, &@2, "Uniform initializer."); destroy_instr_list($2); } | hlsl_prog preproc_directive @@ -2192,7 +2192,7 @@ buffer_declaration: buffer_type any_identifier colon_attribute { if ($3.semantic.name) - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on buffers."); + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on buffers.");
if (!(ctx->cur_buffer = hlsl_new_buffer(ctx, $1, $2, &$3.reg_reservation, @2))) YYABORT; @@ -2249,10 +2249,10 @@ struct_declaration: if (!$3) { if (!$2->name) - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Anonymous struct type must declare a variable."); if (modifiers) - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on struct type declarations."); }
@@ -2274,14 +2274,14 @@ named_struct_spec:
if (hlsl_get_var(ctx->cur_scope, $2)) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" is already declared as a variable.", $2); + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" is already declared as a variable.", $2); YYABORT; }
ret = hlsl_scope_add_type(ctx->cur_scope, $$); if (!ret) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Struct "%s" is already defined.", $2); + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Struct "%s" is already defined.", $2); YYABORT; } } @@ -2312,9 +2312,9 @@ fields_list: { if ((existing = get_struct_field($$, field->name))) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Field "%s" is already defined.", field->name); - hlsl_note(ctx, existing->loc, VKD3D_SHADER_LOG_ERROR, + hlsl_note(ctx, &existing->loc, VKD3D_SHADER_LOG_ERROR, "'%s' was previously defined here.", field->name); vkd3d_free(field); } @@ -2343,7 +2343,7 @@ field: struct vkd3d_string_buffer *string;
if ((string = hlsl_modifiers_to_string(ctx, modifiers))) - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers '%s' are not allowed on struct fields.", string->buffer); hlsl_release_string_buffer(ctx, string); } @@ -2373,21 +2373,21 @@ func_prototype:
if ($1) { - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on functions."); YYABORT; } if ((var = hlsl_get_var(ctx->globals, $3))) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" is already declared as a variable.", $3); - hlsl_note(ctx, var->loc, VKD3D_SHADER_LOG_ERROR, + hlsl_note(ctx, &var->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously declared here.", $3); YYABORT; } if (hlsl_types_are_equal($2, ctx->builtin_types.Void) && $7.semantic.name) { - hlsl_error(ctx, @7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on void functions."); }
@@ -2494,7 +2494,7 @@ param_list: $$ = $1; if (!add_func_parameter(ctx, $$, &$3, @3)) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Parameter "%s" is already declared.", $3.name); YYABORT; } @@ -2529,7 +2529,7 @@ input_mods: struct vkd3d_string_buffer *string;
if ((string = hlsl_modifiers_to_string(ctx, $2))) - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifier "%s" was already specified.", string->buffer); hlsl_release_string_buffer(ctx, string); YYABORT; @@ -2578,14 +2578,14 @@ type:
string = hlsl_type_to_string(ctx, $3); if (string) - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Vector base type %s is not scalar.", string->buffer); hlsl_release_string_buffer(ctx, string); YYABORT; } if ($5 < 1 || $5 > 4) { - hlsl_error(ctx, @5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, "Vector size %d is not between 1 and 4.", $5); YYABORT; } @@ -2604,20 +2604,20 @@ type:
string = hlsl_type_to_string(ctx, $3); if (string) - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Matrix base type %s is not scalar.", string->buffer); hlsl_release_string_buffer(ctx, string); YYABORT; } if ($5 < 1 || $5 > 4) { - hlsl_error(ctx, @5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, "Matrix row count %d is not between 1 and 4.", $5); YYABORT; } if ($7 < 1 || $7 > 4) { - hlsl_error(ctx, @7, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, "Matrix column count %d is not between 1 and 4.", $7); YYABORT; } @@ -2668,7 +2668,7 @@ type:
string = hlsl_type_to_string(ctx, $3); if (string) - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Texture data type %s is not scalar or vector.\n", string->buffer); hlsl_release_string_buffer(ctx, string); } @@ -2683,7 +2683,7 @@ type: { $$ = hlsl_get_type(ctx->cur_scope, $2, true); if ($$->type != HLSL_CLASS_STRUCT) - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" redefined as a structure.", $2); + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" redefined as a structure.", $2); vkd3d_free($2); }
@@ -2706,7 +2706,7 @@ typedef: if ($2 & ~HLSL_TYPE_MODIFIERS_MASK) { struct parse_variable_def *v, *v_next; - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Storage modifiers are not allowed on typedefs."); LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) vkd3d_free(v); @@ -2828,7 +2828,7 @@ arrays:
if (!size) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, "Array size is not a positive integer constant."); vkd3d_free($$.sizes); YYABORT; @@ -2836,7 +2836,7 @@ arrays:
if (size > 65536) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, "Array size %u is not between 1 and 65536.", size); vkd3d_free($$.sizes); YYABORT; @@ -3001,7 +3001,7 @@ selection_statement: struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, condition->data_type))) - hlsl_error(ctx, instr->node.loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &instr->node.loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "if condition type %s is not scalar.", string->buffer); hlsl_release_string_buffer(ctx, string); } @@ -3103,7 +3103,7 @@ primary_expr:
if (!(var = hlsl_get_var(ctx->cur_scope, $1))) { - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable "%s" is not defined.", $1); + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable "%s" is not defined.", $1); YYABORT; } if (!(load = hlsl_new_var_load(ctx, var, @1))) @@ -3137,7 +3137,7 @@ primary_expr: } else { - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier "%s" is not declared.\n", $1); + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier "%s" is not declared.\n", $1); YYABORT; } } @@ -3173,7 +3173,7 @@ postfix_expr:
if (!(field = get_struct_field(type->e.elements, $3))) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field "%s" is not defined.", $3); + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field "%s" is not defined.", $3); YYABORT; }
@@ -3187,7 +3187,7 @@ postfix_expr:
if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle "%s".", $3); + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle "%s".", $3); YYABORT; } list_add_tail($1, &swizzle->node.entry); @@ -3195,7 +3195,7 @@ postfix_expr: } else { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript "%s".", $3); + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript "%s".", $3); YYABORT; } } @@ -3209,7 +3209,7 @@ postfix_expr:
if (index->data_type->type != HLSL_CLASS_SCALAR) { - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); destroy_instr_list($1); YYABORT; } @@ -3234,7 +3234,7 @@ postfix_expr: { if ($1) { - hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on constructors."); free_parse_initializer(&$4); YYABORT; @@ -3244,7 +3244,7 @@ postfix_expr: struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, $2))) - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Constructor data type %s is not numeric.", string->buffer); hlsl_release_string_buffer(ctx, string); free_parse_initializer(&$4); @@ -3252,7 +3252,7 @@ postfix_expr: } if ($2->dimx * $2->dimy != initializer_size(&$4)) { - hlsl_error(ctx, @4, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Expected %u components in constructor, but got %u.", $2->dimx * $2->dimy, initializer_size(&$4)); free_parse_initializer(&$4); @@ -3331,7 +3331,7 @@ unary_expr:
if ($2) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on casts."); YYABORT; } @@ -3347,7 +3347,7 @@ unary_expr: src_string = hlsl_type_to_string(ctx, src_type); dst_string = hlsl_type_to_string(ctx, dst_type); if (src_string && dst_string) - hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.", + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.", src_string->buffer, dst_string->buffer); hlsl_release_string_buffer(ctx, src_string); hlsl_release_string_buffer(ctx, dst_string); @@ -3398,11 +3398,11 @@ shift_expr: add_expr | shift_expr OP_LEFTSHIFT add_expr { - hlsl_fixme(ctx, @$, "Left shift."); + hlsl_fixme(ctx, &@$, "Left shift."); } | shift_expr OP_RIGHTSHIFT add_expr { - hlsl_fixme(ctx, @$, "Right shift."); + hlsl_fixme(ctx, &@$, "Right shift."); }
relational_expr: @@ -3439,42 +3439,42 @@ bitand_expr: equality_expr | bitand_expr '&' equality_expr { - hlsl_fixme(ctx, @$, "Bitwise AND."); + hlsl_fixme(ctx, &@$, "Bitwise AND."); }
bitxor_expr: bitand_expr | bitxor_expr '^' bitand_expr { - hlsl_fixme(ctx, @$, "Bitwise XOR."); + hlsl_fixme(ctx, &@$, "Bitwise XOR."); }
bitor_expr: bitxor_expr | bitor_expr '|' bitxor_expr { - hlsl_fixme(ctx, @$, "Bitwise OR."); + hlsl_fixme(ctx, &@$, "Bitwise OR."); }
logicand_expr: bitor_expr | logicand_expr OP_AND bitor_expr { - hlsl_fixme(ctx, @$, "Logical AND."); + hlsl_fixme(ctx, &@$, "Logical AND."); }
logicor_expr: logicand_expr | logicor_expr OP_OR logicand_expr { - hlsl_fixme(ctx, @$, "Logical OR."); + hlsl_fixme(ctx, &@$, "Logical OR."); }
conditional_expr: logicor_expr | logicor_expr '?' expr ':' assignment_expr { - hlsl_fixme(ctx, @$, "Ternary operator."); + hlsl_fixme(ctx, &@$, "Ternary operator."); }
assignment_expr: @@ -3486,7 +3486,7 @@ assignment_expr:
if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) { - hlsl_error(ctx, @2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); YYABORT; } list_move_tail($3, $1); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 64450c76..570fb5e1 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -113,7 +113,7 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, else if (field->semantic.name) prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); else - hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); } } @@ -184,7 +184,7 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, else if (field->semantic.name) append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); else - hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); } } @@ -1545,7 +1545,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
if (!hlsl_sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx)) { - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); return; } @@ -1562,7 +1562,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
if (!hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage)) { - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); return; } @@ -1653,9 +1653,9 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
if (reserved_buffer && reserved_buffer != buffer) { - hlsl_error(ctx, buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, "Multiple buffers bound to cb%u.", buffer->reservation.index); - hlsl_note(ctx, reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR, + hlsl_note(ctx, &reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR, "Buffer %s is already bound to cb%u.", reserved_buffer->name, buffer->reservation.index); }
@@ -1675,7 +1675,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } else { - hlsl_error(ctx, buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Constant buffers must be allocated to register type 'b'."); } } @@ -1740,10 +1740,10 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type)
if (reserved_object && reserved_object != var) { - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, "Multiple objects bound to %c%u.", type_info->reg_name, var->reg_reservation.index); - hlsl_note(ctx, reserved_object->loc, VKD3D_SHADER_LOG_ERROR, + 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); } @@ -1767,7 +1767,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type) struct vkd3d_string_buffer *type_string;
type_string = hlsl_type_to_string(ctx, var->data_type); - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Object of type '%s' must be bound to register type '%c'.", type_string->buffer, type_info->reg_name); hlsl_release_string_buffer(ctx, type_string); @@ -1808,7 +1808,7 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl if (hlsl_offset_from_deref(deref, &offset)) return offset;
- hlsl_fixme(ctx, deref->offset.node->loc, "Dereference with non-constant offset of type %s.", + hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.", hlsl_node_type_to_string(deref->offset.node->type));
return 0; @@ -1859,7 +1859,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun else { if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Parameter "%s" is missing a semantic.", var->name);
if (var->modifiers & HLSL_STORAGE_IN) @@ -1871,7 +1871,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (entry_func->return_var) { if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name) - hlsl_error(ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point "%s" is missing a return value semantic.", entry_func->func->name);
append_output_var_copy(ctx, &body->instrs, entry_func->return_var); diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 4ff552bc..1868bb70 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -617,7 +617,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b if (instr->data_type->base_type != HLSL_TYPE_FLOAT) { /* These need to be lowered. */ - hlsl_fixme(ctx, instr->loc, "SM1 non-float expression."); + hlsl_fixme(ctx, &instr->loc, "SM1 non-float expression."); return; }
@@ -655,7 +655,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b break;
default: - hlsl_fixme(ctx, instr->loc, "SM1 "%s" expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &instr->loc, "SM1 "%s" expression.", debug_hlsl_expr_op(expr->op)); break; } } @@ -785,12 +785,12 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b if (instr->data_type->type == HLSL_CLASS_MATRIX) { /* These need to be lowered. */ - hlsl_fixme(ctx, instr->loc, "SM1 matrix expression."); + hlsl_fixme(ctx, &instr->loc, "SM1 matrix expression."); continue; } else if (instr->data_type->type == HLSL_CLASS_OBJECT) { - hlsl_fixme(ctx, instr->loc, "Object copy.\n"); + hlsl_fixme(ctx, &instr->loc, "Object copy.\n"); break; }
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index a75abbc0..ef4a4320 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -191,7 +191,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
default: if ((string = hlsl_type_to_string(ctx, var->data_type))) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Invalid data type %s for semantic variable %s.", string->buffer, var->name); hlsl_release_string_buffer(ctx, string); put_u32(&buffer, D3D_REGISTER_COMPONENT_UNKNOWN); @@ -1317,11 +1317,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, expr->node.loc, "Casts from bool to float are not implemented.\n"); + hlsl_fixme(ctx, &expr->node.loc, "Casts from bool to float are not implemented.\n"); break;
case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, expr->node.loc, "Casts from double to float are not implemented.\n"); + hlsl_fixme(ctx, &expr->node.loc, "Casts from double to float are not implemented.\n"); break;
default: @@ -1373,7 +1373,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break;
default: - hlsl_fixme(ctx, expr->node.loc, "SM4 float "%s" expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 float "%s" expression.", debug_hlsl_expr_op(expr->op)); break; } break; @@ -1403,11 +1403,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, expr->node.loc, "SM4 cast from bool to int."); + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to int."); break;
case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, expr->node.loc, "SM4 cast from double to int."); + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to int."); break;
default: @@ -1417,7 +1417,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, }
default: - hlsl_fixme(ctx, expr->node.loc, "SM4 int "%s" expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 int "%s" expression.", debug_hlsl_expr_op(expr->op)); break; } break; @@ -1447,11 +1447,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, expr->node.loc, "SM4 cast from bool to uint.\n"); + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to uint.\n"); break;
case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, expr->node.loc, "SM4 cast from double to uint.\n"); + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to uint.\n"); break;
default: @@ -1461,7 +1461,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, }
default: - hlsl_fixme(ctx, expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break; } break; @@ -1472,7 +1472,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, expr->node.data_type))) - hlsl_fixme(ctx, expr->node.loc, "SM4 %s expression.", string->buffer); + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", string->buffer); hlsl_release_string_buffer(ctx, string); break; } @@ -1561,14 +1561,14 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
if (!load->sampler.var->is_uniform) { - hlsl_fixme(ctx, load->node.loc, "Sample using non-uniform sampler variable."); + hlsl_fixme(ctx, &load->node.loc, "Sample using non-uniform sampler variable."); return; } }
if (!load->resource.var->is_uniform) { - hlsl_fixme(ctx, load->node.loc, "Load from non-uniform resource variable."); + hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable."); return; }
@@ -1580,7 +1580,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
case HLSL_RESOURCE_SAMPLE: if (!load->sampler.var) - hlsl_fixme(ctx, load->node.loc, "SM4 combined sample expression."); + hlsl_fixme(ctx, &load->node.loc, "SM4 combined sample expression."); write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords); break; } @@ -1595,7 +1595,7 @@ static void write_sm4_store(struct hlsl_ctx *ctx,
if (store->lhs.var->data_type->type == HLSL_CLASS_MATRIX) { - hlsl_fixme(ctx, store->node.loc, "Store to a matrix variable.\n"); + hlsl_fixme(ctx, &store->node.loc, "Store to a matrix variable.\n"); return; }
@@ -1649,7 +1649,7 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * } else if (instr->data_type->type == HLSL_CLASS_OBJECT) { - hlsl_fixme(ctx, instr->loc, "Object copy.\n"); + hlsl_fixme(ctx, &instr->loc, "Object copy.\n"); break; }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 2 +- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 68 +++++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index fe0b44d8..8d2e08a6 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -646,7 +646,7 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc }
struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, - struct hlsl_ir_node *val, struct vkd3d_shader_location *loc) + struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { struct hlsl_ir_swizzle *swizzle;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ffc228d8..ea7d6f8c 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -714,7 +714,7 @@ struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *v struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc); struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields); struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, - struct hlsl_ir_node *val, struct vkd3d_shader_location *loc); + struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc); struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 97dc9891..052a7191 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -921,7 +921,7 @@ static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hl }
static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, - struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) + const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) { if (t1->type > HLSL_CLASS_LAST_NUMERIC) { @@ -996,8 +996,9 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, struct vkd3d_shader_location *loc) +static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *type, const struct vkd3d_shader_location *loc) { struct hlsl_ir_expr *expr; unsigned int i; @@ -1014,7 +1015,7 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, }
static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, struct vkd3d_shader_location *loc) + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg};
@@ -1023,7 +1024,7 @@ static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru
static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - struct vkd3d_shader_location *loc) + const struct vkd3d_shader_location *loc) { struct hlsl_type *common_type; enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); @@ -1570,24 +1571,24 @@ static const struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *c }
static bool intrinsic_abs(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], &loc); + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); }
static bool intrinsic_clamp(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_expr *max;
- if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], &loc))) + if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, &max->node, params->args[2], &loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, &max->node, params->args[2], loc); }
static bool intrinsic_cross(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_swizzle *arg1_swzl1, *arg1_swzl2, *arg2_swzl1, *arg2_swzl2; struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1]; @@ -1603,78 +1604,78 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx,
cast_type = hlsl_get_vector_type(ctx, base, 3);
- if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, &loc))) + if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) return false;
- if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, &loc))) + if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) return false;
- if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, &loc))) + if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) return false; list_add_tail(params->instrs, &arg1_swzl1->node.entry);
- if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, &loc))) + if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc))) return false; list_add_tail(params->instrs, &arg2_swzl1->node.entry);
if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, - &arg1_swzl1->node, &arg2_swzl1->node, &loc))) + &arg1_swzl1->node, &arg2_swzl1->node, loc))) return false;
- if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &mul1->node, loc))) + if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &mul1->node, *loc))) return false; list_add_tail(params->instrs, &mul1_neg->entry);
- if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, &loc))) + if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) return false; list_add_tail(params->instrs, &arg1_swzl2->node.entry);
- if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, &loc))) + if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc))) return false; list_add_tail(params->instrs, &arg2_swzl2->node.entry);
if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, - &arg1_swzl2->node, &arg2_swzl2->node, &loc))) + &arg1_swzl2->node, &arg2_swzl2->node, loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &mul2->node, mul1_neg, &loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &mul2->node, mul1_neg, loc); }
static bool intrinsic_max(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], &loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc); }
static bool intrinsic_pow(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *log, *exp; struct hlsl_ir_expr *mul;
- if (!(log = hlsl_new_unary_expr(ctx, HLSL_OP1_LOG2, params->args[0], loc))) + if (!(log = hlsl_new_unary_expr(ctx, HLSL_OP1_LOG2, params->args[0], *loc))) return false; list_add_tail(params->instrs, &log->entry);
- if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, &loc))) + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) return false;
- if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, &mul->node, loc))) + if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, &mul->node, *loc))) return false; list_add_tail(params->instrs, &exp->entry); return true; }
static bool intrinsic_round(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, params->args[0], &loc); + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, params->args[0], loc); }
static bool intrinsic_saturate(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct vkd3d_shader_location loc) + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, params->args[0], &loc); + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, params->args[0], loc); }
static const struct intrinsic_function @@ -1682,7 +1683,8 @@ static const struct intrinsic_function const char *name; int param_count; bool check_numeric; - bool (*handler)(struct hlsl_ctx *ctx, const struct parse_initializer *params, struct vkd3d_shader_location loc); + bool (*handler)(struct hlsl_ctx *ctx, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc); } intrinsic_functions[] = { @@ -1748,7 +1750,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, } }
- if (!intrinsic->handler(ctx, params, loc)) + if (!intrinsic->handler(ctx, params, &loc)) { free_parse_initializer(params); return NULL;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Fix XFAIL_TESTS, writemask-assignop-1.shader_test now passes (thanks to some of the previous patches, I assume).
Makefile.am | 3 +-- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 88bdc0ee..934d7e62 100644 --- a/Makefile.am +++ b/Makefile.am @@ -309,8 +309,7 @@ XFAIL_TESTS = \ tests/sampler.shader_test \ tests/texture-load.shader_test \ tests/texture-load-typed.shader_test \ - tests/trigonometry.shader_test \ - tests/writemask-assignop-1.shader_test + tests/trigonometry.shader_test endif
if BUILD_DEMOS diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index ef4a4320..7f2f9608 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1416,6 +1416,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break; }
+ case HLSL_OP1_NEG: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 int "%s" expression.", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
If a float expression is pre/post decremented and an unsigned one is used to execute it, the unsigned one is first negated (becoming 2^32-1) and then casted to float (becoming 2^32), which leads to an incorrect result.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Makefile.am | 1 - libs/vkd3d-shader/hlsl.c | 12 ++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 934d7e62..20fee06d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -304,7 +304,6 @@ XFAIL_TESTS = \ tests/hlsl-storage-qualifiers.shader_test \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ - tests/math.shader_test \ tests/max.shader_test \ tests/sampler.shader_test \ tests/texture-load.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8d2e08a6..d2ea4c34 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -553,6 +553,18 @@ struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); }
+struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, + const struct vkd3d_shader_location loc) +{ + struct hlsl_ir_constant *c; + + if (!(c = hlsl_alloc(ctx, sizeof(*c)))) + return NULL; + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); + c->value[0].i = n; + return c; +} + struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location loc) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ea7d6f8c..57acf3a0 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -701,6 +701,8 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *no struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location loc); struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc); +struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, + const struct vkd3d_shader_location loc); struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc); struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type, struct vkd3d_shader_location loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 052a7191..131af39b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1255,7 +1255,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in");
- if (!(one = hlsl_new_uint_constant(ctx, 1, loc))) + if (!(one = hlsl_new_int_constant(ctx, 1, loc))) return false; list_add_tail(instrs, &one->node.entry);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- changelog: Update for "vkd3d-shader/hlsl: Pass a vkd3d_shader_location pointer to the intrinsic handler callback."
libs/vkd3d-shader/hlsl.y | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 131af39b..636882c4 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1647,6 +1647,12 @@ static bool intrinsic_max(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc); }
+static bool intrinsic_min(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); +} + static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -1693,6 +1699,7 @@ intrinsic_functions[] = {"clamp", 3, true, intrinsic_clamp}, {"cross", 2, true, intrinsic_cross}, {"max", 2, true, intrinsic_max}, + {"min", 2, true, intrinsic_min}, {"pow", 2, true, intrinsic_pow}, {"round", 1, true, intrinsic_round}, {"saturate", 1, true, intrinsic_saturate},
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 7f2f9608..05b0dc1f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1420,6 +1420,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_unary_op(buffer, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); break;
+ case HLSL_OP2_MAX: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMAX, &expr->node, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 int "%s" expression.", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 05b0dc1f..a17ca594 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1424,6 +1424,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMAX, &expr->node, arg1, arg2); break;
+ case HLSL_OP2_MIN: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMIN, &expr->node, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 int "%s" expression.", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index a17ca594..0d6e8c1a 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1472,6 +1472,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break; }
+ case HLSL_OP2_MAX: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMAX, &expr->node, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 0d6e8c1a..5be8328f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1476,6 +1476,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMAX, &expr->node, arg1, arg2); break;
+ case HLSL_OP2_MIN: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5be8328f..2458018f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -772,6 +772,8 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r { reg->type = VKD3D_SM4_RT_RESOURCE; reg->dim = VKD3D_SM4_DIMENSION_VEC4; + if (swizzle_type) + *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; reg->idx[0] = var->reg.id; reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL;
Signed-off-by: Francisco Casas fcasas@codeweavers.com
December 1, 2021 1:33 PM, "Matteo Bruni" mbruni@codeweavers.com wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5be8328f..2458018f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -772,6 +772,8 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r { reg->type = VKD3D_SM4_RT_RESOURCE; reg->dim = VKD3D_SM4_DIMENSION_VEC4;
- if (swizzle_type)
- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4;
reg->idx[0] = var->reg.id; reg->idx_count = 1;
*writemask = VKD3DSP_WRITEMASK_ALL;
2.26.3
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 01/12/21 17:15, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5be8328f..2458018f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -772,6 +772,8 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r { reg->type = VKD3D_SM4_RT_RESOURCE; reg->dim = VKD3D_SM4_DIMENSION_VEC4;
if (swizzle_type)
*swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; reg->idx[0] = var->reg.id; reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 01/12/21 17:14, Matteo Bruni wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
changelog: Did a bunch of changes, mostly stylistic.
I dropped the existing sign-offs here and in some of the following patches since I changed enough of the code that I wouldn't feel those would still be valid.
Sorry it took me a while to review and fix up these patches and come up with a hopefully consistent patch series. I don't expect the whole series to go in in one go but I wanted to "show" the end result to possibly unblock anyone that wants to start preparing more patches on top (but I'd refrain from sending until this series is resolved one way or another :)).
This series should supersede or otherwise render invalid all the other pending vkd3d-shader/hlsl patches.
libs/vkd3d-shader/hlsl.c | 20 ++- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 217 ++++++++++++++++++++++++++++++- 3 files changed, 232 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9824c56d..8895f5bc 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1097,6 +1097,19 @@ const char *debug_hlsl_writemask(unsigned int writemask) return vkd3d_dbg_sprintf(".%s", string); }
+const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int size) +{
- static const char components[] = {'x', 'y', 'z', 'w'};
- char string[5];
- unsigned int i;
- assert(size <= ARRAY_SIZE(components));
- for (i = 0; i < size; ++i)
string[i] = components[(swizzle >> i * 2) & 3];
- string[size] = 0;
- return vkd3d_dbg_sprintf(".%s", string);
+}
- static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant) { struct hlsl_type *type = constant->node.data_type;
@@ -1278,18 +1291,15 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls unsigned int i;
dump_src(buffer, &swizzle->val);
- vkd3d_string_buffer_printf(buffer, "."); if (swizzle->val.node->data_type->dimy > 1) {
vkd3d_string_buffer_printf(buffer, "."); for (i = 0; i < swizzle->node.data_type->dimx; ++i) vkd3d_string_buffer_printf(buffer, "_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf); } else {
static const char c[] = {'x', 'y', 'z', 'w'};
for (i = 0; i < swizzle->node.data_type->dimx; ++i)
vkd3d_string_buffer_printf(buffer, "%c", c[(swizzle->swizzle >> i * 2) & 0x3]);
}vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_swizzle(swizzle->swizzle, swizzle->node.data_type->dimx)); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e7bdb45e..eb11b4ab 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -667,6 +667,7 @@ static inline struct hlsl_type *hlsl_get_numeric_type(const struct hlsl_ctx *ctx const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); const char *debug_hlsl_writemask(unsigned int writemask); +const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int count);
struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type); struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8b0eb9b3..d3957f89 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -237,6 +237,216 @@ static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) hlsl_free_instr(old); }
+struct copy_propagation_value +{
- struct hlsl_ir_node *node;
- unsigned int component;
+};
+struct copy_propagation_var_def +{
- struct rb_entry entry;
- struct hlsl_ir_var *var;
- struct copy_propagation_value values[];
+};
+struct copy_propagation_state +{
- struct rb_tree var_defs;
+};
+static int copy_propagation_var_def_compare(const void *key, const struct rb_entry *entry) +{
- struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
- uintptr_t key_int = (uintptr_t)key, entry_int = (uintptr_t)var_def->var;
- return (key_int > entry_int) - (key_int < entry_int);
+}
+static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *context) +{
- struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
- vkd3d_free(var_def);
+}
+static struct copy_propagation_var_def *copy_propagation_get_var_def(struct copy_propagation_state *state,
struct hlsl_ir_var *var)
+{
- struct rb_entry *entry = rb_get(&state->var_defs, var);
- if (entry)
return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
- else
return NULL;
+}
+static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx,
struct copy_propagation_state *state, struct hlsl_ir_var *var)
+{
- struct rb_entry *entry = rb_get(&state->var_defs, var);
- struct copy_propagation_var_def *var_def;
- int res;
- if (entry)
return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
- if (!(var_def = hlsl_alloc(ctx, offsetof(struct copy_propagation_var_def, values[var->data_type->reg_size]))))
return NULL;
- var_def->var = var;
- res = rb_put(&state->var_defs, var, &var_def->entry);
- assert(!res);
- return var_def;
+}
+static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def) +{
- TRACE("Invalidate variable %s.\n", var_def->var->name);
- memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size);
+}
+static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int offset,
unsigned char writemask, struct hlsl_ir_node *node)
+{
- unsigned int i, j = 0;
- for (i = 0; i < 4; ++i)
- {
if (writemask & (1u << i))
{
TRACE("Variable %s[%u] is written by instruction %p%s.\n",
var_def->var->name, offset + i, node, debug_hlsl_writemask(1u << i));
var_def->values[offset + i].node = node;
var_def->values[offset + i].component = j++;
}
- }
+}
+static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_propagation_var_def *var_def,
unsigned int offset, unsigned int count, unsigned int *swizzle)
+{
- struct hlsl_ir_node *node = NULL;
- unsigned int i;
- assert(offset + count <= var_def->var->data_type->reg_size);
- *swizzle = 0;
- for (i = 0; i < count; ++i)
- {
if (!node)
node = var_def->values[offset + i].node;
else if (node != var_def->values[offset + i].node)
return NULL;
*swizzle |= var_def->values[offset + i].component << i * 2;
- }
- return node;
+}
+static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load,
struct copy_propagation_state *state)
+{
- struct hlsl_ir_node *node = &load->node, *new_node;
- struct copy_propagation_var_def *var_def;
- struct hlsl_type *type = node->data_type;
- struct hlsl_ir_swizzle *swizzle_node;
- struct hlsl_deref *src = &load->src;
- struct hlsl_ir_var *var = src->var;
- unsigned int offset, swizzle;
- if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR)
return false;
- if (!hlsl_offset_from_deref(src, &offset))
return false;
- if (!(var_def = copy_propagation_get_var_def(state, var)))
return false;
- if (!(new_node = copy_propagation_compute_replacement(var_def, offset, type->dimx, &swizzle)))
- {
TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
return false;
- }
- TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n",
var->name, offset, offset + type->dimx, new_node, debug_hlsl_swizzle(swizzle, 4));
- if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, type->dimx, new_node, &node->loc)))
return false;
- list_add_before(&node->entry, &swizzle_node->node.entry);
- replace_node(node, &swizzle_node->node);
- return true;
+}
+static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store,
struct copy_propagation_state *state)
+{
- struct copy_propagation_var_def *var_def;
- struct hlsl_deref *lhs = &store->lhs;
- struct hlsl_ir_var *var = lhs->var;
- unsigned int offset;
- if (!(var_def = copy_propagation_create_var_def(ctx, state, var)))
return;
- if (hlsl_offset_from_deref(lhs, &offset))
copy_propagation_set_value(var_def, offset, store->writemask, store->rhs.node);
- else
copy_propagation_invalidate_whole_variable(var_def);
+}
+static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct copy_propagation_state *state)
+{
- struct hlsl_ir_node *instr, *next;
- bool progress = false;
- LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry)
- {
switch (instr->type)
{
case HLSL_IR_LOAD:
progress |= copy_propagation_analyze_load(ctx, hlsl_ir_load(instr), state);
break;
case HLSL_IR_STORE:
copy_propagation_record_store(ctx, hlsl_ir_store(instr), state);
break;
case HLSL_IR_IF:
FIXME("Copy propagation doesn't support conditionals yet, leaving.\n");
return progress;
case HLSL_IR_LOOP:
FIXME("Copy propagation doesn't support loops yet, leaving.\n");
return progress;
default:
break;
}
- }
- return progress;
+}
+static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) +{
- struct copy_propagation_state state;
- bool progress;
- rb_init(&state.var_defs, copy_propagation_var_def_compare);
- progress = copy_propagation_transform_block(ctx, block, &state);
- rb_destroy(&state.var_defs, copy_propagation_var_def_destroy, NULL);
- return progress;
+}
- static bool is_vec1(const struct hlsl_type *type) { return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1);
@@ -1421,7 +1631,12 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun progress |= transform_ir(ctx, split_struct_copies, body, NULL); } while (progress);
- while (transform_ir(ctx, fold_constants, body, NULL));
do
{
progress = transform_ir(ctx, fold_constants, body, NULL);
progress |= copy_propagation_execute(ctx, body);
}
while (progress); transform_ir(ctx, remove_trivial_swizzles, body, NULL);
if (ctx->profile->major_version < 4)