Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 3 ++ libs/vkd3d-shader/hlsl_codegen.c | 49 +++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d2ea4c34a..3a571b946 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -196,6 +196,8 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type }
case HLSL_CLASS_OBJECT: + /* For convenience when performing copy propagation. */ + type->reg_size = 1; break; } } @@ -273,6 +275,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ type->dimy = 1; type->sampler_dim = dim; type->e.resource_format = format; + hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); return type; } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e43e6378e..e426101fa 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -394,9 +394,26 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l struct hlsl_deref *src = &load->src; struct hlsl_ir_var *var = src->var; unsigned int offset, swizzle; + unsigned int dimx = 0;
- if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) - return false; + switch (type->type) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + dimx = type->dimx; + break; + + case HLSL_CLASS_OBJECT: + dimx = 1; + break; + + case HLSL_CLASS_MATRIX: + case HLSL_CLASS_ARRAY: + case HLSL_CLASS_STRUCT: + /* FIXME: Actually we shouldn't even get here, but we don't split + * matrices yet. */ + return false; + }
if (!hlsl_offset_from_deref(src, &offset)) return false; @@ -404,18 +421,22 @@ 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_replacement(var_def, offset, type->dimx, &swizzle))) + if (!(new_node = copy_propagation_compute_replacement(var_def, offset, dimx, &swizzle))) { - TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx); + TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + 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); + var->name, offset, offset + dimx, new_node, debug_hlsl_swizzle(swizzle, 4)); + if (type->type != HLSL_CLASS_OBJECT) + { + if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, dimx, new_node, &node->loc))) + return false; + list_add_before(&node->entry, &swizzle_node->node.entry); + new_node = &swizzle_node->node; + } + replace_node(node, new_node); return true; }
@@ -431,9 +452,17 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s return;
if (hlsl_offset_from_deref(lhs, &offset)) - copy_propagation_set_value(var_def, offset, store->writemask, store->rhs.node); + { + unsigned int writemask = store->writemask; + + if (store->rhs.node->data_type->type == HLSL_CLASS_OBJECT) + writemask = VKD3DSP_WRITEMASK_0; + copy_propagation_set_value(var_def, offset, 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,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 41 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e426101fa..02ed398be 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -307,8 +307,8 @@ static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *conte 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) +static struct copy_propagation_var_def *copy_propagation_get_var_def(const struct copy_propagation_state *state, + const struct hlsl_ir_var *var) { struct rb_entry *entry = rb_get(&state->var_defs, var);
@@ -362,11 +362,19 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, } }
-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) +static struct hlsl_ir_node *copy_propagation_compute_replacement(const struct copy_propagation_state *state, + const struct hlsl_deref *deref, unsigned int count, unsigned int *swizzle) { + const struct hlsl_ir_var *var = deref->var; + struct copy_propagation_var_def *var_def; struct hlsl_ir_node *node = NULL; - unsigned int i; + unsigned int offset, i; + + if (!hlsl_offset_from_deref(deref, &offset)) + return NULL; + + if (!(var_def = copy_propagation_get_var_def(state, var))) + return NULL;
assert(offset + count <= var_def->var->data_type->reg_size);
@@ -377,10 +385,15 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_pro if (!node) node = var_def->values[offset + i].node; else if (node != var_def->values[offset + i].node) + { + TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + count); return NULL; + } *swizzle |= var_def->values[offset + i].component << i * 2; }
+ TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n", + var->name, offset, offset + count, node, debug_hlsl_swizzle(*swizzle, count)); return node; }
@@ -388,13 +401,10 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l 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; unsigned int dimx = 0; + unsigned int swizzle;
switch (type->type) { @@ -415,20 +425,9 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l 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, dimx, &swizzle))) - { - TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + dimx); + if (!(new_node = copy_propagation_compute_replacement(state, &load->src, dimx, &swizzle))) return false; - }
- TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n", - var->name, offset, offset + dimx, new_node, debug_hlsl_swizzle(swizzle, 4)); if (type->type != HLSL_CLASS_OBJECT) { if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, dimx, new_node, &node->loc)))
Hi,
On 22/12/21 00:08, Zebediah Figura wrote:
@@ -377,10 +385,15 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_pro if (!node) node = var_def->values[offset + i].node; else if (node != var_def->values[offset + i].node)
{
TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + count); return NULL;
}
That's fine for me, but I guess that usually vkd3d's policy is that if one branch of an "if ... else if ... else" chain has braces, then all of them must have. Or did I misunderstand it?
Giovanni.
On 12/22/21 03:23, Giovanni Mascellani wrote:
Hi,
On 22/12/21 00:08, Zebediah Figura wrote:
@@ -377,10 +385,15 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_pro          if (!node)              node = var_def->values[offset + i].node;          else if (node != var_def->values[offset + i].node) +       { +           TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + count);              return NULL; +       }
That's fine for me, but I guess that usually vkd3d's policy is that if one branch of an "if ... else if ... else" chain has braces, then all of them must have. Or did I misunderstand it?
Yes, that's correct, but I missed it.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 02ed398be..41c48e065 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1504,7 +1504,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (var->is_uniform) + if (var->is_uniform && var->data_type->type != HLSL_CLASS_OBJECT) { if (var->is_param) var->buffer = ctx->params_buffer;
This patch is something of an argument for storing the resource and sampler variables as hlsl_src rather than hlsl_deref. I'm still inclined to avoid this, because that would require the variable to be unchanged between the load and resource load, and that feels like a tricky and dangerous invariant to preserve.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 3 --- libs/vkd3d-shader/hlsl_codegen.c | 39 +++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 0c2fbf7d7..80742d97a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -307,9 +307,6 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/max.shader_test \ - tests/sampler.shader_test \ - tests/texture-load.shader_test \ - tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test endif
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 41c48e065..bc2a160cf 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -397,8 +397,8 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(const struct co return node; }
-static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, - struct copy_propagation_state *state) +static bool copy_propagation_transform_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 hlsl_type *type = node->data_type; @@ -439,6 +439,35 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l return true; }
+static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, + struct hlsl_deref *deref, struct copy_propagation_state *state) +{ + struct hlsl_ir_load *load; + struct hlsl_ir_node *node; + unsigned int swizzle; + + if (!(node = copy_propagation_compute_replacement(state, deref, 1, &swizzle))) + return false; + + /* Only HLSL_IR_LOAD can produce an object. */ + load = hlsl_ir_load(node); + deref->var = load->src.var; + hlsl_src_remove(&deref->offset); + hlsl_src_from_node(&deref->offset, load->src.offset.node); + return true; +} + +static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, + struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) +{ + bool progress = false; + + progress |= copy_propagation_transform_object_load(ctx, &load->resource, state); + if (load->sampler.var) + progress |= copy_propagation_transform_object_load(ctx, &load->sampler, state); + return progress; +} + static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, struct copy_propagation_state *state) { @@ -475,7 +504,11 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b switch (instr->type) { case HLSL_IR_LOAD: - progress |= copy_propagation_analyze_load(ctx, hlsl_ir_load(instr), state); + progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); + break; + + case HLSL_IR_RESOURCE_LOAD: + progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); break;
case HLSL_IR_STORE:
Hi,
On 22/12/21 00:08, Zebediah Figura wrote:
This patch is something of an argument for storing the resource and sampler variables as hlsl_src rather than hlsl_deref. I'm still inclined to avoid this, because that would require the variable to be unchanged between the load and resource load, and that feels like a tricky and dangerous invariant to preserve.
I have no opinion of whether using a hlsl_src or a hlsl_deref (not yet, at least :-P ), but I don't understand your second sentence. Is it possible to mutate a texture or sampler variable?
Giovanni.
On 12/22/21 03:37, Giovanni Mascellani wrote:
Hi,
On 22/12/21 00:08, Zebediah Figura wrote:
This patch is something of an argument for storing the resource and sampler variables as hlsl_src rather than hlsl_deref. I'm still inclined to avoid this, because that would require the variable to be unchanged between the load and resource load, and that feels like a tricky and dangerous invariant to preserve.
I have no opinion of whether using a hlsl_src or a hlsl_deref (not yet, at least :-P ), but I don't understand your second sentence. Is it possible to mutate a texture or sampler variable?
Sure, it's possible to mutate any variable.
To expand, what I mean is that the alternative—where we use hlsl_src—means we'd need to have a separate HLSL_IR_LOAD instruction, and then at codegen time we reach through it and retrieve the variable from that. That works—objects can only be returned by LOAD instructions—but the problem is that you can get something like:
Texture2D | 2: t1 | 3: t1 = t2 float4 | 4: sample(@2, ...)
I guess we could validate at codegen time that t1 isn't written to (after all, if it is, we have a problem anyway)...
Hi,
On 22/12/21 19:03, Zebediah Figura (she/her) wrote:
To expand, what I mean is that the alternative—where we use hlsl_src—means we'd need to have a separate HLSL_IR_LOAD instruction, and then at codegen time we reach through it and retrieve the variable from that. That works—objects can only be returned by LOAD instructions—but the problem is that you can get something like:
Texture2D | 2: t1 Â Â Â Â Â Â Â Â Â | 3: t1 = t2 float4Â Â Â | 4: sample(@2, ...)
I guess we could validate at codegen time that t1 isn't written to (after all, if it is, we have a problem anyway)...
Ah, yes, I see what you mean.
I wrote and erased this email a few times changing my point of view every time, and in the end I think I just came to your conclusion, which I see with two different layers (well, at least two).
The upper layer is that what we call "texture variable" behave rather as references, point to underlying immutable texture entities (after all, if this wasn't the case you couldn't even assign one to another). Expression "@2" really means "the entity that t1 was pointing to at line 2", not "the variable t1 itself". In much the same way as, if you had
float | 2: x
the expression "@2" would mean "the value variable x had a line 2", not "the variable x" or "the value variable x has now".
We can treat objects this way and we should be able to manipulate it in much the same ways as we do for numbers.
In practice (the second layer), all object parameters must be completely known at compilation time, because you cannot represent object references in DXBC, only entities (by mean of their "register"). So after all copy propagation, dead code elimination and possibly other optimizations have run, no stores to objects must remain. Not just between a load and the corresponding usage: no stores at all. Once that is true, the confusion between entities and references doesn't happen anymore and you can identify variables with their loads. Which is, as I get it, what you were saying.
All of this doesn't say much between whether resource loads should use hlsl_src or hlsl_deref, though I guess that it says that hlsl_src should not be a problem in itself.
Giovanni.
On Wed, Dec 22, 2021 at 12:08 AM Zebediah Figura zfigura@codeweavers.com wrote:
This patch is something of an argument for storing the resource and sampler variables as hlsl_src rather than hlsl_deref. I'm still inclined to avoid this, because that would require the variable to be unchanged between the load and resource load, and that feels like a tricky and dangerous invariant to preserve.
I don't think it's a big deal either way. Sticking to hlsl_deref for now seems fine to me, I don't think we're expecting a lot of juggling of those objects aside from what we already have (which is sort of an artifact of our general IR setup). At any rate, it shouldn't be too big of a mess if we change our mind at some point, as I'd expect the changes to be decently self-contained.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 2458018fe..e90a76dbe 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -748,7 +748,7 @@ struct sm4_instruction } dsts[1]; unsigned int dst_count;
- struct + struct sm4_src_register { struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type; @@ -890,6 +890,16 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write *writemask = instr->reg.writemask; }
+static void sm4_src_from_node(struct sm4_src_register *src, + const struct hlsl_ir_node *instr, unsigned int map_writemask) +{ + unsigned int writemask; + + sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); + if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) + src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); +} + static uint32_t sm4_encode_register(const struct sm4_register *reg) { return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT) @@ -1132,7 +1142,6 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, unsigned int src_mod) { struct sm4_instruction instr; - unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = opcode; @@ -1140,8 +1149,7 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ 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, src); - instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].writemask); instr.srcs[0].reg.mod = src_mod; instr.src_count = 1;
@@ -1152,7 +1160,6 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { struct sm4_instruction instr; - unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = opcode; @@ -1160,10 +1167,8 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d 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, src1); - instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); - sm4_register_from_node(&instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, src2); - instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); instr.src_count = 2;
write_sm4_instruction(buffer, &instr); @@ -1218,8 +1223,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf 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_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
/* Mipmap level is in the last component in the IR, but needs to be in the W * component in the instruction. */ @@ -1263,8 +1267,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, resource, resource_type); @@ -1508,12 +1511,10 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf .opcode = VKD3D_SM4_OP_IF | VKD3D_SM4_CONDITIONAL_NZ, .src_count = 1, }; - unsigned int writemask;
assert(iff->condition.node->data_type->dimx == 1);
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, iff->condition.node); - instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask); + sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); write_sm4_instruction(buffer, &instr);
write_sm4_block(ctx, buffer, &iff->then_instrs); @@ -1628,8 +1629,7 @@ static void write_sm4_store(struct hlsl_ctx *ctx, instr.dsts[0].writemask = hlsl_combine_writemasks(writemask, store->writemask); instr.dst_count = 1;
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, rhs); - instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[0], rhs, instr.dsts[0].writemask); instr.src_count = 1;
write_sm4_instruction(buffer, &instr);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 2458018fe..e90a76dbe 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -748,7 +748,7 @@ struct sm4_instruction } dsts[1]; unsigned int dst_count;
- struct
- struct sm4_src_register { struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type;
@@ -890,6 +890,16 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write *writemask = instr->reg.writemask; }
+static void sm4_src_from_node(struct sm4_src_register *src,
const struct hlsl_ir_node *instr, unsigned int map_writemask)
+{
- unsigned int writemask;
- sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr);
- if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4)
src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask);
+}
- static uint32_t sm4_encode_register(const struct sm4_register *reg) { return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT)
@@ -1132,7 +1142,6 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, unsigned int src_mod) { struct sm4_instruction instr;
unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
@@ -1140,8 +1149,7 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ 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, src);
- instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
- sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].writemask); instr.srcs[0].reg.mod = src_mod; instr.src_count = 1;
@@ -1152,7 +1160,6 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { struct sm4_instruction instr;
unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
@@ -1160,10 +1167,8 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d 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, src1);
- instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
- sm4_register_from_node(&instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, src2);
- instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask);
sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); instr.src_count = 2;
write_sm4_instruction(buffer, &instr);
@@ -1218,8 +1223,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf 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_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
/* Mipmap level is in the last component in the IR, but needs to be in the W
- component in the instruction. */
@@ -1263,8 +1267,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
sm4_register_from_deref(ctx, &instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, resource, resource_type);
@@ -1508,12 +1511,10 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf .opcode = VKD3D_SM4_OP_IF | VKD3D_SM4_CONDITIONAL_NZ, .src_count = 1, };
unsigned int writemask;
assert(iff->condition.node->data_type->dimx == 1);
sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, iff->condition.node);
instr.srcs[0].swizzle = hlsl_swizzle_from_writemask(writemask);
sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); write_sm4_instruction(buffer, &instr);
write_sm4_block(ctx, buffer, &iff->then_instrs);
@@ -1628,8 +1629,7 @@ static void write_sm4_store(struct hlsl_ctx *ctx, instr.dsts[0].writemask = hlsl_combine_writemasks(writemask, store->writemask); instr.dst_count = 1;
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, rhs);
- instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
sm4_src_from_node(&instr.srcs[0], rhs, instr.dsts[0].writemask); instr.src_count = 1;
write_sm4_instruction(buffer, &instr);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e90a76dbe..0bb35a3c8 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -877,6 +877,16 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r } }
+static void sm4_src_from_deref(struct hlsl_ctx *ctx, struct sm4_src_register *src, + const struct hlsl_deref *deref, const struct hlsl_type *data_type, unsigned int map_writemask) +{ + unsigned int writemask; + + sm4_register_from_deref(ctx, &src->reg, &writemask, &src->swizzle_type, deref, data_type); + if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) + src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); +} + static void sm4_register_from_node(struct sm4_register *reg, unsigned int *writemask, enum vkd3d_sm4_swizzle_type *swizzle_type, const struct hlsl_ir_node *instr) { @@ -1215,7 +1225,6 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf const struct hlsl_deref *resource, const struct hlsl_ir_node *coords) { struct sm4_instruction instr; - unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_LD; @@ -1245,9 +1254,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf assert(0); }
- 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_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask);
instr.src_count = 2;
@@ -1259,7 +1266,6 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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; @@ -1268,14 +1274,8 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - - 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); - + sm4_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask); + sm4_src_from_deref(ctx, &instr.srcs[2], sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL); instr.src_count = 3;
write_sm4_instruction(buffer, &instr); @@ -1536,7 +1536,6 @@ static void write_sm4_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_load *load) { struct sm4_instruction instr; - unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; @@ -1544,9 +1543,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &load->node); instr.dst_count = 1;
- sm4_register_from_deref(ctx, &instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, - &load->src, load->node.data_type); - instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask); + sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, load->node.data_type, instr.dsts[0].writemask); instr.src_count = 1;
write_sm4_instruction(buffer, &instr);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e90a76dbe..0bb35a3c8 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -877,6 +877,16 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r } }
+static void sm4_src_from_deref(struct hlsl_ctx *ctx, struct sm4_src_register *src,
const struct hlsl_deref *deref, const struct hlsl_type *data_type, unsigned int map_writemask)
+{
- unsigned int writemask;
- sm4_register_from_deref(ctx, &src->reg, &writemask, &src->swizzle_type, deref, data_type);
- if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4)
src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask);
+}
- static void sm4_register_from_node(struct sm4_register *reg, unsigned int *writemask, enum vkd3d_sm4_swizzle_type *swizzle_type, const struct hlsl_ir_node *instr) {
@@ -1215,7 +1225,6 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf const struct hlsl_deref *resource, const struct hlsl_ir_node *coords) { struct sm4_instruction instr;
unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_LD;
@@ -1245,9 +1254,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf assert(0); }
- 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_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask);
instr.src_count = 2;
@@ -1259,7 +1266,6 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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;
@@ -1268,14 +1274,8 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
- 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);
sm4_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask);
sm4_src_from_deref(ctx, &instr.srcs[2], sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL); instr.src_count = 3;
write_sm4_instruction(buffer, &instr);
@@ -1536,7 +1536,6 @@ static void write_sm4_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_load *load) { struct sm4_instruction instr;
unsigned int writemask;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
@@ -1544,9 +1543,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &load->node); instr.dst_count = 1;
- sm4_register_from_deref(ctx, &instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type,
&load->src, load->node.data_type);
- instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[0].writemask);
sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, load->node.data_type, instr.dsts[0].writemask); instr.src_count = 1;
write_sm4_instruction(buffer, &instr);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 0bb35a3c8..e2b2d6dfa 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -741,7 +741,7 @@ struct sm4_instruction { enum vkd3d_sm4_opcode opcode;
- struct + struct sm4_dst_register { struct sm4_register reg; unsigned int writemask; @@ -893,13 +893,19 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write assert(instr->reg.allocated); reg->type = VKD3D_SM4_RT_TEMP; reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; reg->idx[0] = instr->reg.id; reg->idx_count = 1; *writemask = instr->reg.writemask; }
+static void sm4_dst_from_node(struct sm4_dst_register *dst, const struct hlsl_ir_node *instr) +{ + unsigned int swizzle_type; + + sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr); +} + static void sm4_src_from_node(struct sm4_src_register *src, const struct hlsl_ir_node *instr, unsigned int map_writemask) { @@ -1156,7 +1162,7 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst); + sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].writemask); @@ -1174,7 +1180,7 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst); + sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); @@ -1194,7 +1200,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &constant->node); + sm4_dst_from_node(&instr.dsts[0], &constant->node); instr.dst_count = 1;
instr.srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; @@ -1229,7 +1235,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_LD;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst); + sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); @@ -1270,7 +1276,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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); + sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); @@ -1540,7 +1546,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &load->node); + sm4_dst_from_node(&instr.dsts[0], &load->node); instr.dst_count = 1;
sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, load->node.data_type, instr.dsts[0].writemask); @@ -1641,7 +1647,7 @@ static void write_sm4_swizzle(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &swizzle->node); + sm4_dst_from_node(&instr.dsts[0], &swizzle->node); instr.dst_count = 1;
sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, swizzle->val.node);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 0bb35a3c8..e2b2d6dfa 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -741,7 +741,7 @@ struct sm4_instruction { enum vkd3d_sm4_opcode opcode;
- struct
- struct sm4_dst_register { struct sm4_register reg; unsigned int writemask;
@@ -893,13 +893,19 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write assert(instr->reg.allocated); reg->type = VKD3D_SM4_RT_TEMP; reg->dim = VKD3D_SM4_DIMENSION_VEC4;
- if (swizzle_type)
*swizzle_type = VKD3D_SM4_SWIZZLE_VEC4;
- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; reg->idx[0] = instr->reg.id; reg->idx_count = 1; *writemask = instr->reg.writemask; }
+static void sm4_dst_from_node(struct sm4_dst_register *dst, const struct hlsl_ir_node *instr) +{
- unsigned int swizzle_type;
- sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr);
+}
- static void sm4_src_from_node(struct sm4_src_register *src, const struct hlsl_ir_node *instr, unsigned int map_writemask) {
@@ -1156,7 +1162,7 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst);
sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].writemask);
@@ -1174,7 +1180,7 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d memset(&instr, 0, sizeof(instr)); instr.opcode = opcode;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst);
sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask);
@@ -1194,7 +1200,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &constant->node);
sm4_dst_from_node(&instr.dsts[0], &constant->node); instr.dst_count = 1;
instr.srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_NONE;
@@ -1229,7 +1235,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_LD;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst);
sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
@@ -1270,7 +1276,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer 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);
sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
@@ -1540,7 +1546,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &load->node);
sm4_dst_from_node(&instr.dsts[0], &load->node); instr.dst_count = 1;
sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, load->node.data_type, instr.dsts[0].writemask);
@@ -1641,7 +1647,7 @@ static void write_sm4_swizzle(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV;
- sm4_register_from_node(&instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, &swizzle->node);
sm4_dst_from_node(&instr.dsts[0], &swizzle->node); instr.dst_count = 1;
sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, swizzle->val.node);
Hi,
On 22/12/21 00:08, Zebediah Figura wrote:
@@ -893,13 +893,19 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write assert(instr->reg.allocated); reg->type = VKD3D_SM4_RT_TEMP; reg->dim = VKD3D_SM4_DIMENSION_VEC4;
- if (swizzle_type)
*swizzle_type = VKD3D_SM4_SWIZZLE_VEC4;
- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; reg->idx[0] = instr->reg.id; reg->idx_count = 1; *writemask = instr->reg.writemask; }
+static void sm4_dst_from_node(struct sm4_dst_register *dst, const struct hlsl_ir_node *instr) +{
- unsigned int swizzle_type;
- sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr);
+}
I am fine either way, but I'd have leaved the possibility for swizzle_type to be NULL, so that the programmer's intention of ignoring that output is more evident.
Giovanni.
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Replaced the FIXME in sm4_encode_instruction_modifier() with an assert(); avoid nameless unions; minor stylistic tweaks.
libs/vkd3d-shader/hlsl_sm4.c | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e2b2d6dfa..73024e3bb 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -727,6 +727,44 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ } }
+struct sm4_instruction_modifier +{ + enum vkd3d_sm4_instruction_modifier type; + + union + { + struct + { + int u, v, w; + } aoffimmi; + } u; +}; + +static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_modifier *imod) +{ + uint32_t word = 0; + + word |= VKD3D_SM4_MODIFIER_MASK & imod->type; + + switch (imod->type) + { + case VKD3D_SM4_MODIFIER_AOFFIMMI: + assert(-8 <= imod->u.aoffimmi.u && imod->u.aoffimmi.u <= 7); + assert(-8 <= imod->u.aoffimmi.v && imod->u.aoffimmi.v <= 7); + assert(-8 <= imod->u.aoffimmi.w && imod->u.aoffimmi.w <= 7); + word |= ((uint32_t)imod->u.aoffimmi.u & 0xf) << VKD3D_SM4_AOFFIMMI_U_SHIFT; + word |= ((uint32_t)imod->u.aoffimmi.v & 0xf) << VKD3D_SM4_AOFFIMMI_V_SHIFT; + word |= ((uint32_t)imod->u.aoffimmi.w & 0xf) << VKD3D_SM4_AOFFIMMI_W_SHIFT; + break; + + default: + assert(0); + break; + } + + return word; +} + struct sm4_register { enum vkd3d_sm4_register_type type; @@ -741,6 +779,9 @@ struct sm4_instruction { enum vkd3d_sm4_opcode opcode;
+ struct sm4_instruction_modifier modifiers[1]; + unsigned int modifier_count; + struct sm4_dst_register { struct sm4_register reg; @@ -939,6 +980,7 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st uint32_t token = instr->opcode; unsigned int size = 1, i, j;
+ size += instr->modifier_count; for (i = 0; i < instr->dst_count; ++i) size += sm4_register_order(&instr->dsts[i].reg); for (i = 0; i < instr->src_count; ++i) @@ -946,8 +988,19 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st size += instr->idx_count;
token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); + + if (instr->modifier_count > 0) + token |= VKD3D_SM4_INSTRUCTION_MODIFIER; put_u32(buffer, token);
+ for (i = 0; i < instr->modifier_count; ++i) + { + token = sm4_encode_instruction_modifier(&instr->modifiers[i]); + if (instr->modifier_count > i + 1) + token |= VKD3D_SM4_INSTRUCTION_MODIFIER; + put_u32(buffer, token); + } + for (i = 0; i < instr->dst_count; ++i) { token = sm4_encode_register(&instr->dsts[i].reg);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Replaced the FIXME in sm4_encode_instruction_modifier() with an assert(); avoid nameless unions; minor stylistic tweaks.
libs/vkd3d-shader/hlsl_sm4.c | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e2b2d6dfa..73024e3bb 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -727,6 +727,44 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ } }
+struct sm4_instruction_modifier +{
- enum vkd3d_sm4_instruction_modifier type;
- union
- {
struct
{
int u, v, w;
} aoffimmi;
- } u;
+};
+static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_modifier *imod) +{
- uint32_t word = 0;
- word |= VKD3D_SM4_MODIFIER_MASK & imod->type;
- switch (imod->type)
- {
case VKD3D_SM4_MODIFIER_AOFFIMMI:
assert(-8 <= imod->u.aoffimmi.u && imod->u.aoffimmi.u <= 7);
assert(-8 <= imod->u.aoffimmi.v && imod->u.aoffimmi.v <= 7);
assert(-8 <= imod->u.aoffimmi.w && imod->u.aoffimmi.w <= 7);
word |= ((uint32_t)imod->u.aoffimmi.u & 0xf) << VKD3D_SM4_AOFFIMMI_U_SHIFT;
word |= ((uint32_t)imod->u.aoffimmi.v & 0xf) << VKD3D_SM4_AOFFIMMI_V_SHIFT;
word |= ((uint32_t)imod->u.aoffimmi.w & 0xf) << VKD3D_SM4_AOFFIMMI_W_SHIFT;
break;
default:
assert(0);
break;
- }
- return word;
+}
- struct sm4_register { enum vkd3d_sm4_register_type type;
@@ -741,6 +779,9 @@ struct sm4_instruction { enum vkd3d_sm4_opcode opcode;
- struct sm4_instruction_modifier modifiers[1];
- unsigned int modifier_count;
struct sm4_dst_register { struct sm4_register reg;
@@ -939,6 +980,7 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st uint32_t token = instr->opcode; unsigned int size = 1, i, j;
- size += instr->modifier_count; for (i = 0; i < instr->dst_count; ++i) size += sm4_register_order(&instr->dsts[i].reg); for (i = 0; i < instr->src_count; ++i)
@@ -946,8 +988,19 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st size += instr->idx_count;
token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
if (instr->modifier_count > 0)
token |= VKD3D_SM4_INSTRUCTION_MODIFIER; put_u32(buffer, token);
for (i = 0; i < instr->modifier_count; ++i)
{
token = sm4_encode_instruction_modifier(&instr->modifiers[i]);
if (instr->modifier_count > i + 1)
token |= VKD3D_SM4_INSTRUCTION_MODIFIER;
put_u32(buffer, token);
}
for (i = 0; i < instr->dst_count; ++i) { token = sm4_encode_register(&instr->dsts[i].reg);
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 9 ++++++++- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 16 +++++++++++----- libs/vkd3d-shader/hlsl_codegen.c | 2 ++ 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3a571b946..26175008d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -644,7 +644,7 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - const struct vkd3d_shader_location *loc) + struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load;
@@ -657,6 +657,7 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc load->sampler.var = sampler; hlsl_src_from_node(&load->sampler.offset, sampler_offset); hlsl_src_from_node(&load->coords, coords); + hlsl_src_from_node(&load->texel_offset, texel_offset); return load; }
@@ -1287,6 +1288,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->sampler); vkd3d_string_buffer_printf(buffer, ", coords = "); dump_src(buffer, &load->coords); + if (load->texel_offset.node) + { + vkd3d_string_buffer_printf(buffer, ", offset = "); + dump_src(buffer, &load->texel_offset); + } vkd3d_string_buffer_printf(buffer, ")"); }
@@ -1460,6 +1466,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) hlsl_src_remove(&load->coords); hlsl_src_remove(&load->sampler.offset); hlsl_src_remove(&load->resource.offset); + hlsl_src_remove(&load->texel_offset); vkd3d_free(load); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 57acf3a01..2396adb40 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -386,6 +386,7 @@ struct hlsl_ir_resource_load enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; struct hlsl_src coords; + struct hlsl_src texel_offset; };
struct hlsl_ir_store @@ -710,7 +711,7 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5a17449a3..9b1e5c071 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1875,7 +1875,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false;
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, - object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, loc))) + object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, NULL, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; @@ -1885,6 +1885,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim); const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; + struct hlsl_ir_node *offset = NULL; struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords;
@@ -1894,8 +1895,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl "Wrong number of arguments to method 'Sample': expected 2 or 3, but got %u.", params->args_count); return false; } - if (params->args_count == 3) - FIXME("Ignoring offset parameter.\n");
sampler_type = params->args[0]->data_type; if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER @@ -1915,11 +1914,18 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - coords = params->args[1]; + return false; + + if (params->args_count == 3) + { + if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + return false; + }
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node, - sampler_load->src.var, sampler_load->src.offset.node, coords, loc))) + sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index bc2a160cf..9d8066203 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1050,6 +1050,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop }
load->coords.node->last_read = instr->index; + if (load->texel_offset.node) + load->texel_offset.node->last_read = instr->index; break; } case HLSL_IR_SWIZZLE:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 9 ++++++++- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 16 +++++++++++----- libs/vkd3d-shader/hlsl_codegen.c | 2 ++ 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3a571b946..26175008d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -644,7 +644,7 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords,
const struct vkd3d_shader_location *loc)
{ struct hlsl_ir_resource_load *load;struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc)
@@ -657,6 +657,7 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc load->sampler.var = sampler; hlsl_src_from_node(&load->sampler.offset, sampler_offset); hlsl_src_from_node(&load->coords, coords);
- hlsl_src_from_node(&load->texel_offset, texel_offset); return load; }
@@ -1287,6 +1288,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->sampler); vkd3d_string_buffer_printf(buffer, ", coords = "); dump_src(buffer, &load->coords);
- if (load->texel_offset.node)
- {
vkd3d_string_buffer_printf(buffer, ", offset = ");
dump_src(buffer, &load->texel_offset);
- } vkd3d_string_buffer_printf(buffer, ")"); }
@@ -1460,6 +1466,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) hlsl_src_remove(&load->coords); hlsl_src_remove(&load->sampler.offset); hlsl_src_remove(&load->resource.offset);
- hlsl_src_remove(&load->texel_offset); vkd3d_free(load); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 57acf3a01..2396adb40 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -386,6 +386,7 @@ struct hlsl_ir_resource_load enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; struct hlsl_src coords;
struct hlsl_src texel_offset; };
struct hlsl_ir_store
@@ -710,7 +711,7 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords,
const struct vkd3d_shader_location *loc);
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc);struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5a17449a3..9b1e5c071 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1875,7 +1875,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false;
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD,
object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, loc)))
object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, NULL, loc))) return false; list_add_tail(instrs, &load->node.entry); return true;
@@ -1885,6 +1885,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim); const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL; struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords;
@@ -1894,8 +1895,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl "Wrong number of arguments to method 'Sample': expected 2 or 3, but got %u.", params->args_count); return false; }
if (params->args_count == 3)
FIXME("Ignoring offset parameter.\n"); sampler_type = params->args[0]->data_type; if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER
@@ -1915,11 +1914,18 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
coords = params->args[1];
return false;
if (params->args_count == 3)
{
if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2],
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc)))
return false;
} if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node,
sampler_load->src.var, sampler_load->src.offset.node, coords, loc)))
sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true;
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index bc2a160cf..9d8066203 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1050,6 +1050,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop }
load->coords.node->last_read = instr->index;
if (load->texel_offset.node)
load->texel_offset.node->last_read = instr->index; break; } case HLSL_IR_SWIZZLE:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Simplify logic in encode_texel_offset_as_aoffimmi() a bit; minor stylistic tweaks.
libs/vkd3d-shader/hlsl_sm4.c | 40 ++++++++++++++++++++++-- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 73024e3bb..127628677 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1044,6 +1044,29 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st put_u32(buffer, instr->idx[j]); }
+static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, + const struct hlsl_ir_node *texel_offset) +{ + struct sm4_instruction_modifier modif; + struct hlsl_ir_constant *offset; + + if (!texel_offset || texel_offset->type != HLSL_IR_CONSTANT) + return false; + offset = hlsl_ir_constant(texel_offset); + + modif.type = VKD3D_SM4_MODIFIER_AOFFIMMI; + modif.u.aoffimmi.u = offset->value[0].i; + modif.u.aoffimmi.v = offset->value[1].i; + modif.u.aoffimmi.w = offset->value[2].i; + if (modif.u.aoffimmi.u < -8 || modif.u.aoffimmi.u > 7 + || modif.u.aoffimmi.v < -8 || modif.u.aoffimmi.v > 7 + || modif.u.aoffimmi.w < -8 || modif.u.aoffimmi.w > 7) + return false; + + instr->modifiers[instr->modifier_count++] = modif; + return true; +} + static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_buffer *cbuffer) { const struct sm4_instruction instr = @@ -1322,13 +1345,24 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf
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) + const struct hlsl_deref *resource, const struct hlsl_deref *sampler, + const struct hlsl_ir_node *coords, const struct hlsl_ir_node *texel_offset) { struct sm4_instruction instr;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_SAMPLE;
+ if (texel_offset) + { + if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) + { + hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, + "Offset must resolve to integer literal in the range -8 to 7.\n"); + return; + } + } + sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
@@ -1628,6 +1662,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load) { const struct hlsl_type *resource_type = load->resource.var->data_type; + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node;
if (load->sampler.var) @@ -1660,7 +1695,8 @@ 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."); - write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords); + write_sm4_sample(ctx, buffer, resource_type, &load->node, + &load->resource, &load->sampler, coords, texel_offset); break; } } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 62073cf1b..718bb2024 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -114,6 +114,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS = 5015, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION = 5016, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED = 5017, + VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET = 5018,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Simplify logic in encode_texel_offset_as_aoffimmi() a bit; minor stylistic tweaks.
libs/vkd3d-shader/hlsl_sm4.c | 40 ++++++++++++++++++++++-- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 73024e3bb..127628677 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1044,6 +1044,29 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st put_u32(buffer, instr->idx[j]); }
+static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr,
const struct hlsl_ir_node *texel_offset)
+{
- struct sm4_instruction_modifier modif;
- struct hlsl_ir_constant *offset;
- if (!texel_offset || texel_offset->type != HLSL_IR_CONSTANT)
return false;
- offset = hlsl_ir_constant(texel_offset);
- modif.type = VKD3D_SM4_MODIFIER_AOFFIMMI;
- modif.u.aoffimmi.u = offset->value[0].i;
- modif.u.aoffimmi.v = offset->value[1].i;
- modif.u.aoffimmi.w = offset->value[2].i;
- if (modif.u.aoffimmi.u < -8 || modif.u.aoffimmi.u > 7
|| modif.u.aoffimmi.v < -8 || modif.u.aoffimmi.v > 7
|| modif.u.aoffimmi.w < -8 || modif.u.aoffimmi.w > 7)
return false;
- instr->modifiers[instr->modifier_count++] = modif;
- return true;
+}
- static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_buffer *cbuffer) { const struct sm4_instruction instr =
@@ -1322,13 +1345,24 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf
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)
const struct hlsl_deref *resource, const struct hlsl_deref *sampler,
const struct hlsl_ir_node *coords, const struct hlsl_ir_node *texel_offset)
{ struct sm4_instruction instr;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_SAMPLE;
if (texel_offset)
{
if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset))
{
hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET,
"Offset must resolve to integer literal in the range -8 to 7.\n");
return;
}
}
sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1;
@@ -1628,6 +1662,7 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load) { const struct hlsl_type *resource_type = load->resource.var->data_type;
const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node;
if (load->sampler.var)
@@ -1660,7 +1695,8 @@ 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.");
write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords);
write_sm4_sample(ctx, buffer, resource_type, &load->node,
}&load->resource, &load->sampler, coords, texel_offset); break; }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 62073cf1b..718bb2024 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -114,6 +114,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS = 5015, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION = 5016, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED = 5017,
VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET = 5018,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Change subject prefix to "tests".
Makefile.am | 2 ++ tests/sampler-offset.shader_test | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/sampler-offset.shader_test
diff --git a/Makefile.am b/Makefile.am index 80742d97a..d0729681a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,6 +95,7 @@ vkd3d_shader_tests = \ tests/preproc-misc.shader_test \ tests/round.shader_test \ tests/sampler.shader_test \ + tests/sampler-offset.shader_test \ tests/saturate.shader_test \ tests/swizzle-0.shader_test \ tests/swizzle-1.shader_test \ @@ -307,6 +308,7 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/max.shader_test \ + tests/sampler-offset.shader_test \ tests/trigonometry.shader_test endif
diff --git a/tests/sampler-offset.shader_test b/tests/sampler-offset.shader_test new file mode 100644 index 000000000..83900c55e --- /dev/null +++ b/tests/sampler-offset.shader_test @@ -0,0 +1,51 @@ +[sampler 0] +filter point point point +address clamp clamp clamp + +[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4 + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Sample(s, float2(0.5, 0.5), int2(0, 1)); +} + +[test] +draw quad +probe all rgba (0.1, 0.2, 0.5, 0.0) + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Sample(s, float2(0.1, 0.5), int2(2, 1)); +} + +[test] +draw quad +probe all rgba (0.2, 0.2, 0.0, 0.4) + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Sample(s, float2(0.9, 0.5), int2(-2, 1)); +} + +[test] +draw quad +probe all rgba (0.0, 0.2, 0.0, 0.4)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Change subject prefix to "tests".
Makefile.am | 2 ++ tests/sampler-offset.shader_test | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/sampler-offset.shader_test
diff --git a/Makefile.am b/Makefile.am index 80742d97a..d0729681a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,6 +95,7 @@ vkd3d_shader_tests = \ tests/preproc-misc.shader_test \ tests/round.shader_test \ tests/sampler.shader_test \
- tests/sampler-offset.shader_test \ tests/saturate.shader_test \ tests/swizzle-0.shader_test \ tests/swizzle-1.shader_test \
@@ -307,6 +308,7 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/max.shader_test \
- tests/sampler-offset.shader_test \ tests/trigonometry.shader_test endif
diff --git a/tests/sampler-offset.shader_test b/tests/sampler-offset.shader_test new file mode 100644 index 000000000..83900c55e --- /dev/null +++ b/tests/sampler-offset.shader_test @@ -0,0 +1,51 @@ +[sampler 0] +filter point point point +address clamp clamp clamp
+[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Sample(s, float2(0.5, 0.5), int2(0, 1));
+}
+[test] +draw quad +probe all rgba (0.1, 0.2, 0.5, 0.0)
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Sample(s, float2(0.1, 0.5), int2(2, 1));
+}
+[test] +draw quad +probe all rgba (0.2, 0.2, 0.0, 0.4)
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Sample(s, float2(0.9, 0.5), int2(-2, 1));
+}
+[test] +draw quad +probe all rgba (0.0, 0.2, 0.0, 0.4)
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample", + [HLSL_RESOURCE_GATHER_RED] = "gather_red", + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", };
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, + HLSL_RESOURCE_GATHER_RED, + HLSL_RESOURCE_GATHER_GREEN, + HLSL_RESOURCE_GATHER_BLUE, + HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; } + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) + { + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim); + enum hlsl_resource_load_type load_type; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_node *offset = NULL; + struct hlsl_ir_load *sampler_load; + struct hlsl_type *result_type; + struct hlsl_ir_node *coords; + unsigned int read_channel; + + if (!strcmp(name, "GatherGreen")) + { + load_type = HLSL_RESOURCE_GATHER_GREEN; + read_channel = 1; + } + else if (!strcmp(name, "GatherBlue")) + { + load_type = HLSL_RESOURCE_GATHER_BLUE; + read_channel = 2; + } + else if (!strcmp(name, "GatherAlpha")) + { + load_type = HLSL_RESOURCE_GATHER_ALPHA; + read_channel = 3; + } + else + { + load_type = HLSL_RESOURCE_GATHER_RED; + read_channel = 0; + } + + if (!strcmp(name, "Gather")) + { + if (params->args_count != 2 && params->args_count != 3) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Gather': expected 2 or 3, but got %u.", params->args_count); + return false; + } + } + else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 2,3,4,6 or 7, but got %u.", name, params->args_count); + return false; + } + + if (params->args_count == 4 || params->args_count == 7) + hlsl_fixme(ctx, loc, "Tiled resource fully mapped status."); + + if (params->args_count == 6 || params->args_count == 7) + hlsl_fixme(ctx, loc, "Multiple Gather() offset parameters."); + + if (params->args_count == 3 || params->args_count == 4) + { + if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) + return false; + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (read_channel >= object_type->e.resource_format->dimx) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Method %s() requires at least %d channels.", name, read_channel + 1); + return false; + } + + result_type = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); + + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false; + + if (!(load = hlsl_new_resource_load(ctx, result_type, + load_type, object_load->src.var, object_load->src.offset.node, + sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } else { struct vkd3d_string_buffer *string; diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 127628677..6805e7442 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -794,7 +794,7 @@ struct sm4_instruction struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type; unsigned int swizzle; - } srcs[3]; + } srcs[4]; unsigned int src_count;
uint32_t idx[2]; @@ -1658,6 +1658,41 @@ static void write_sm4_loop(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_gather(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, unsigned int swizzle, const struct hlsl_ir_node *texel_offset) +{ + struct sm4_src_register *src; + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + + instr.opcode = VKD3D_SM4_OP_GATHER4; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); + + /* FIXME: Use an aoffimmi modifier if possible. */ + if (texel_offset) + { + instr.opcode = VKD3D_SM5_OP_GATHER4_PO; + sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); + } + + sm4_src_from_deref(ctx, &instr.srcs[instr.src_count++], resource, resource_type, instr.dsts[0].writemask); + + src = &instr.srcs[instr.src_count++]; + sm4_src_from_deref(ctx, src, sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL); + src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; + src->swizzle_type = VKD3D_SM4_SWIZZLE_SCALAR; + src->swizzle = swizzle; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load) { @@ -1698,6 +1733,26 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, texel_offset); break; + + case HLSL_RESOURCE_GATHER_RED: + write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, + &load->sampler, coords, HLSL_SWIZZLE(X, X, X, X), texel_offset); + break; + + case HLSL_RESOURCE_GATHER_GREEN: + write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, + &load->sampler, coords, HLSL_SWIZZLE(Y, Y, Y, Y), texel_offset); + break; + + case HLSL_RESOURCE_GATHER_BLUE: + write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, + &load->sampler, coords, HLSL_SWIZZLE(Z, Z, Z, Z), texel_offset); + break; + + case HLSL_RESOURCE_GATHER_ALPHA: + write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, + &load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset); + break; } }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
load_type = HLSL_RESOURCE_GATHER_GREEN;
read_channel = 1;
}
else if (!strcmp(name, "GatherBlue"))
{
load_type = HLSL_RESOURCE_GATHER_BLUE;
read_channel = 2;
}
else if (!strcmp(name, "GatherAlpha"))
{
load_type = HLSL_RESOURCE_GATHER_ALPHA;
read_channel = 3;
}
else
{
load_type = HLSL_RESOURCE_GATHER_RED;
read_channel = 0;
}
if (!strcmp(name, "Gather"))
{
if (params->args_count != 2 && params->args_count != 3)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
"Wrong number of arguments to method 'Gather': expected 2 or 3, but got %u.", params->args_count);
return false;
}
}
else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
"Wrong number of arguments to method '%s': expected 2,3,4,6 or 7, but got %u.", name, params->args_count);
return false;
}
if (params->args_count == 4 || params->args_count == 7)
hlsl_fixme(ctx, loc, "Tiled resource fully mapped status.");
if (params->args_count == 6 || params->args_count == 7)
hlsl_fixme(ctx, loc, "Multiple Gather() offset parameters.");
if (params->args_count == 3 || params->args_count == 4)
{
if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2],
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc)))
return false;
}
sampler_type = params->args[0]->data_type;
if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER
|| sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
{
struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, sampler_type)))
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer);
hlsl_release_string_buffer(ctx, string);
return false;
}
if (read_channel >= object_type->e.resource_format->dimx)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Method %s() requires at least %d channels.", name, read_channel + 1);
return false;
}
result_type = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4);
/* Only HLSL_IR_LOAD can return an object. */
sampler_load = hlsl_ir_load(params->args[0]);
if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1],
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
return false;
if (!(load = hlsl_new_resource_load(ctx, result_type,
load_type, object_load->src.var, object_load->src.offset.node,
sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc)))
return false;
list_add_tail(instrs, &load->node.entry);
return true;
- } else { struct vkd3d_string_buffer *string;
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 127628677..6805e7442 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -794,7 +794,7 @@ struct sm4_instruction struct sm4_register reg; enum vkd3d_sm4_swizzle_type swizzle_type; unsigned int swizzle;
- } srcs[3];
} srcs[4]; unsigned int src_count;
uint32_t idx[2];
@@ -1658,6 +1658,41 @@ static void write_sm4_loop(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_gather(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, unsigned int swizzle, const struct hlsl_ir_node *texel_offset)
+{
- struct sm4_src_register *src;
- struct sm4_instruction instr;
- memset(&instr, 0, sizeof(instr));
- instr.opcode = VKD3D_SM4_OP_GATHER4;
- sm4_dst_from_node(&instr.dsts[0], dst);
- instr.dst_count = 1;
- sm4_src_from_node(&instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL);
- /* FIXME: Use an aoffimmi modifier if possible. */
- if (texel_offset)
- {
instr.opcode = VKD3D_SM5_OP_GATHER4_PO;
sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL);
- }
- sm4_src_from_deref(ctx, &instr.srcs[instr.src_count++], resource, resource_type, instr.dsts[0].writemask);
- src = &instr.srcs[instr.src_count++];
- sm4_src_from_deref(ctx, src, sampler, sampler->var->data_type, VKD3DSP_WRITEMASK_ALL);
- src->reg.dim = VKD3D_SM4_DIMENSION_VEC4;
- src->swizzle_type = VKD3D_SM4_SWIZZLE_SCALAR;
- src->swizzle = swizzle;
- write_sm4_instruction(buffer, &instr);
+}
- static void write_sm4_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_load *load) {
@@ -1698,6 +1733,26 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, texel_offset); break;
case HLSL_RESOURCE_GATHER_RED:
write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource,
&load->sampler, coords, HLSL_SWIZZLE(X, X, X, X), texel_offset);
break;
case HLSL_RESOURCE_GATHER_GREEN:
write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource,
&load->sampler, coords, HLSL_SWIZZLE(Y, Y, Y, Y), texel_offset);
break;
case HLSL_RESOURCE_GATHER_BLUE:
write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource,
&load->sampler, coords, HLSL_SWIZZLE(Z, Z, Z, Z), texel_offset);
break;
case HLSL_RESOURCE_GATHER_ALPHA:
write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource,
&load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset);
}break; }
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
};
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
- HLSL_RESOURCE_GATHER_RED,
- HLSL_RESOURCE_GATHER_GREEN,
- HLSL_RESOURCE_GATHER_BLUE,
- HLSL_RESOURCE_GATHER_ALPHA,
};
struct hlsl_ir_resource_load diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
load_type = HLSL_RESOURCE_GATHER_GREEN;
read_channel = 1;
}
else if (!strcmp(name, "GatherBlue"))
{
load_type = HLSL_RESOURCE_GATHER_BLUE;
read_channel = 2;
}
else if (!strcmp(name, "GatherAlpha"))
{
load_type = HLSL_RESOURCE_GATHER_ALPHA;
read_channel = 3;
}
else
{
load_type = HLSL_RESOURCE_GATHER_RED;
read_channel = 0;
}
if (!strcmp(name, "Gather"))
{
if (params->args_count != 2 && params->args_count != 3)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
"Wrong number of arguments to method 'Gather': expected 2 or 3, but got %u.", params->args_count);
return false;
}
}
else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
"Wrong number of arguments to method '%s': expected 2,3,4,6 or 7, but got %u.", name, params->args_count);
Nitpick, spacing after comma is inconsistent.
return false;
}
if (params->args_count == 4 || params->args_count == 7)
hlsl_fixme(ctx, loc, "Tiled resource fully mapped status.");
Nitpick 2, this fixme message seems a bit obscure. It makes sense when reading it word by word but it didn't quite work for me at a first glance. Maybe "Tiled resource status argument" or so? It's also okay to leave it as is.
if (params->args_count == 6 || params->args_count == 7)
hlsl_fixme(ctx, loc, "Multiple Gather() offset parameters.");
if (params->args_count == 3 || params->args_count == 4)
{
if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2],
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc)))
return false;
}
sampler_type = params->args[0]->data_type;
if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER
|| sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
{
struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, sampler_type)))
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer);
I think usually one uses 1-based indices in this type of compiler messages.
hlsl_release_string_buffer(ctx, string);
return false;
}
if (read_channel >= object_type->e.resource_format->dimx)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Method %s() requires at least %d channels.", name, read_channel + 1);
%u
I'll be resending this patch too so I can make those changes myself, if there are no objections.
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
};
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
- HLSL_RESOURCE_GATHER_RED,
- HLSL_RESOURCE_GATHER_GREEN,
- HLSL_RESOURCE_GATHER_BLUE,
- HLSL_RESOURCE_GATHER_ALPHA,
};
struct hlsl_ir_resource_load diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
On 1/26/22 08:52, Matteo Bruni wrote:
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
I agree that a table would help here. I'm not sure I understand the concern about intrinsics that can't be inlined, though; can you please elaborate?
On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 08:52, Matteo Bruni wrote:
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
I agree that a table would help here. I'm not sure I understand the concern about intrinsics that can't be inlined, though; can you please elaborate?
I'm referring to those intrinsics that shouldn't become expressions but stay as function calls, to make sure they aren't reordered or otherwise optimized (e.g. barriers). As we discussed earlier, they could also be represented by a separate instruction type, in which case they are sort of inlined anyway and, I guess, the existing intrinsic_functions[] table could be a good place for the string-to-enum conversion I'm proposing.
On 1/26/22 15:48, Matteo Bruni wrote:
On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 08:52, Matteo Bruni wrote:
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
I agree that a table would help here. I'm not sure I understand the concern about intrinsics that can't be inlined, though; can you please elaborate?
I'm referring to those intrinsics that shouldn't become expressions but stay as function calls, to make sure they aren't reordered or otherwise optimized (e.g. barriers). As we discussed earlier, they could also be represented by a separate instruction type, in which case they are sort of inlined anyway and, I guess, the existing intrinsic_functions[] table could be a good place for the string-to-enum conversion I'm proposing.
That seems like an orthogonal problem; there's nothing about the way intrinsic functions are currently handled that is tied to EXPR types. I.e. there's no reason an handler from the intrinsic_functions table has to emit an HLSL_IR_EXPR; it could just as easily emit HLSL_IR_INTRINSIC or HLSL_IR_BARRIER or whatever it'd end up being called.
On Wed, Jan 26, 2022 at 11:00 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 15:48, Matteo Bruni wrote:
On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 08:52, Matteo Bruni wrote:
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused status_out_arg variable, expand the srcs[] array to have size 4, use sm4 register helpers, minor stylistic tweaks.
libs/vkd3d-shader/hlsl.c | 4 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- 4 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 26175008d..856fb0f9d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample",
[HLSL_RESOURCE_GATHER_RED] = "gather_red",
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", }; vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2396adb40..49fa8d9d3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -378,6 +378,10 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
HLSL_RESOURCE_GATHER_ALPHA, };
struct hlsl_ir_resource_load
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9b1e5c071..460ba44bb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl list_add_tail(instrs, &load->node.entry); return true; }
- else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
|| !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha"))
- {
const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
enum hlsl_resource_load_type load_type;
const struct hlsl_type *sampler_type;
struct hlsl_ir_resource_load *load;
struct hlsl_ir_node *offset = NULL;
struct hlsl_ir_load *sampler_load;
struct hlsl_type *result_type;
struct hlsl_ir_node *coords;
unsigned int read_channel;
if (!strcmp(name, "GatherGreen"))
{
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
I agree that a table would help here. I'm not sure I understand the concern about intrinsics that can't be inlined, though; can you please elaborate?
I'm referring to those intrinsics that shouldn't become expressions but stay as function calls, to make sure they aren't reordered or otherwise optimized (e.g. barriers). As we discussed earlier, they could also be represented by a separate instruction type, in which case they are sort of inlined anyway and, I guess, the existing intrinsic_functions[] table could be a good place for the string-to-enum conversion I'm proposing.
That seems like an orthogonal problem; there's nothing about the way intrinsic functions are currently handled that is tied to EXPR types. I.e. there's no reason an handler from the intrinsic_functions table has to emit an HLSL_IR_EXPR; it could just as easily emit HLSL_IR_INTRINSIC or HLSL_IR_BARRIER or whatever it'd end up being called.
Yeah. Just saying that that's what I meant with "intrinsics that can't be inlined".
On Wed, Jan 26, 2022 at 11:02 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Jan 26, 2022 at 11:00 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 15:48, Matteo Bruni wrote:
On Wed, Jan 26, 2022 at 10:33 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 1/26/22 08:52, Matteo Bruni wrote:
On Wed, Jan 19, 2022 at 1:06 PM Matteo Bruni matteo.mystral@gmail.com wrote:
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote: > > From: Francisco Casas fcasas@codeweavers.com > > Signed-off-by: Francisco Casas fcasas@codeweavers.com > Signed-off-by: Zebediah Figura zfigura@codeweavers.com > --- > v5: Strip newlines from hlsl_fixme(), get rid of the as-yet-unused > status_out_arg variable, expand the srcs[] array to have size 4, use sm4 > register helpers, minor stylistic tweaks. > > libs/vkd3d-shader/hlsl.c | 4 ++ > libs/vkd3d-shader/hlsl.h | 4 ++ > libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++++++++++++++++++++++++ > libs/vkd3d-shader/hlsl_sm4.c | 57 ++++++++++++++++++++- > 4 files changed, 163 insertions(+), 1 deletion(-) > > diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c > index 26175008d..856fb0f9d 100644 > --- a/libs/vkd3d-shader/hlsl.c > +++ b/libs/vkd3d-shader/hlsl.c > @@ -1280,6 +1280,10 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru > { > [HLSL_RESOURCE_LOAD] = "load_resource", > [HLSL_RESOURCE_SAMPLE] = "sample", > + [HLSL_RESOURCE_GATHER_RED] = "gather_red", > + [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", > + [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", > + [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", > }; > > vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); > diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h > index 2396adb40..49fa8d9d3 100644 > --- a/libs/vkd3d-shader/hlsl.h > +++ b/libs/vkd3d-shader/hlsl.h > @@ -378,6 +378,10 @@ enum hlsl_resource_load_type > { > HLSL_RESOURCE_LOAD, > HLSL_RESOURCE_SAMPLE, > + HLSL_RESOURCE_GATHER_RED, > + HLSL_RESOURCE_GATHER_GREEN, > + HLSL_RESOURCE_GATHER_BLUE, > + HLSL_RESOURCE_GATHER_ALPHA, > }; > > struct hlsl_ir_resource_load > diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y > index 9b1e5c071..460ba44bb 100644 > --- a/libs/vkd3d-shader/hlsl.y > +++ b/libs/vkd3d-shader/hlsl.y > @@ -1930,6 +1930,105 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl > list_add_tail(instrs, &load->node.entry); > return true; > } > + else if (!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") > + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) > + { > + const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim); > + enum hlsl_resource_load_type load_type; > + const struct hlsl_type *sampler_type; > + struct hlsl_ir_resource_load *load; > + struct hlsl_ir_node *offset = NULL; > + struct hlsl_ir_load *sampler_load; > + struct hlsl_type *result_type; > + struct hlsl_ir_node *coords; > + unsigned int read_channel; > + > + if (!strcmp(name, "GatherGreen")) > + {
At some point we probably want to introduce an enum for intrinsics and e.g. table-driven intrinsic_from_{function,method}() helpers to find out which intrinsic a call is supposed to match, if any. Repeatedly string-matching the function name like this is a bit ugly and it's only going to get worse as we introduce more intrinsics. The intrinsics currently in hlsl.y, intrinsic_functions[] sidestep the problem but that's only going to apply to those that can be inlined straight away.
I agree that a table would help here. I'm not sure I understand the concern about intrinsics that can't be inlined, though; can you please elaborate?
I'm referring to those intrinsics that shouldn't become expressions but stay as function calls, to make sure they aren't reordered or otherwise optimized (e.g. barriers). As we discussed earlier, they could also be represented by a separate instruction type, in which case they are sort of inlined anyway and, I guess, the existing intrinsic_functions[] table could be a good place for the string-to-enum conversion I'm proposing.
That seems like an orthogonal problem; there's nothing about the way intrinsic functions are currently handled that is tied to EXPR types. I.e. there's no reason an handler from the intrinsic_functions table has to emit an HLSL_IR_EXPR; it could just as easily emit HLSL_IR_INTRINSIC or HLSL_IR_BARRIER or whatever it'd end up being called.
Yeah. Just saying that that's what I meant with "intrinsics that can't be inlined".
To be clear, in my original comment I really don't care about the inlining or not aspect aka representing "atomic" intrinsics as a non-inlined call or in some other way. I guess I should have left the final sentence out, it only added to the confusion.
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Split from the previous patch, add require directives to allow the tests to pass with native d3dcompiler.
Makefile.am | 3 + tests/hlsl-gather-offset.shader_test | 101 +++++++++++++++++++++++ tests/hlsl-gather.shader_test | 115 +++++++++++++++++++++++++++ tests/shader_runner_d3d12.c | 63 ++++++++++++++- 4 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 tests/hlsl-gather-offset.shader_test create mode 100644 tests/hlsl-gather.shader_test
diff --git a/Makefile.am b/Makefile.am index d0729681a..3aaa67b55 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,8 @@ vkd3d_shader_tests = \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \ + tests/hlsl-gather-offset.shader_test \ + tests/hlsl-gather.shader_test \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-invalid.shader_test \ tests/hlsl-majority-pragma.shader_test \ @@ -295,6 +297,7 @@ XFAIL_TESTS = \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \ + tests/hlsl-gather.shader_test \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-majority-pragma.shader_test \ tests/hlsl-majority-typedef.shader_test \ diff --git a/tests/hlsl-gather-offset.shader_test b/tests/hlsl-gather-offset.shader_test new file mode 100644 index 000000000..51e6a6b64 --- /dev/null +++ b/tests/hlsl-gather-offset.shader_test @@ -0,0 +1,101 @@ +[require] +shader model >= 4.1 + + +[sampler 0] +filter linear linear linear +address clamp clamp clamp + +[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4 + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Gather(s, float2(0.2, 0.2), int2(1, 0)); +} + +[test] +draw quad +probe all rgba (0.1, 0.2, 0.2, 0.1) + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherRed(s, float2(0.6, 0.6), int2(-1, 0)); +} + +[test] +draw quad +probe all rgba (0.0, 0.1, 0.1, 0.0) + + +[require] +shader model >= 5.0 + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 1)); +} + +[test] +draw quad +probe all rgba (0.2, 0.2, 0.1, 0.1) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherGreen(s, float2(0.8, 0.8), int2(-1, -1)); +} + +[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherBlue(s, float2(0.2, 0.8), int2(1, 0)); +} + +[test] +draw quad +probe all rgba (0.5, 0.0, 0.5, 0.0) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherAlpha(s, float2(0.2, 0.8), int2(0, -1)); +} + +[test] +draw quad +probe all rgba (0.0, 0.4, 0.0, 0.4) diff --git a/tests/hlsl-gather.shader_test b/tests/hlsl-gather.shader_test new file mode 100644 index 000000000..57af23d02 --- /dev/null +++ b/tests/hlsl-gather.shader_test @@ -0,0 +1,115 @@ +[require] +shader model >= 4.1 + + +[sampler 0] +filter linear linear linear +address clamp clamp clamp + +[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4 + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.Gather(s, float2(0.2, 0.2)); +} + +[test] +draw quad +probe all rgba (0.0, 0.1, 0.1, 0.0) + + +[pixel shader] +sampler s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherRed(s, float2(0.6, 0.6), int2(0, 0)); +} + +[test] +draw quad +probe all rgba (0.1, 0.2, 0.2, 0.1) + + +[require] +shader model >= 5.0 + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 0)); +} + +[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherGreen(s, float2(0.8, 0.8)); +} + +[test] +draw quad +probe all rgba (0.2, 0.2, 0.1, 0.1) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0)); +} + +[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherBlue(s, float2(0.2, 0.8), int2(0, 0)); +} + +[test] +draw quad +probe all rgba (0.0, 0.5, 0.0, 0.5) + + +[pixel shader] +SamplerState s; +Texture2D t; + +float4 main() : sv_target +{ + return t.GatherAlpha(s, float2(0.2, 0.8), int2(0, 0)); +} + +[test] +draw quad +probe all rgba (0.4, 0.0, 0.4, 0.0) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index d404895fb..fa73b31b7 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -115,9 +115,18 @@ struct texture unsigned int root_index; };
+enum shader_model +{ + SHADER_MODEL_4_0 = 0, + SHADER_MODEL_4_1, + SHADER_MODEL_5_0, + SHADER_MODEL_5_1, +}; + struct shader_context { struct test_context c; + enum shader_model minimum_shader_model;
ID3D10Blob *ps_code;
@@ -160,6 +169,7 @@ enum parse_state STATE_NONE, STATE_PREPROC, STATE_PREPROC_INVALID, + STATE_REQUIRE, STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_PIXEL, @@ -182,6 +192,36 @@ static bool match_string(const char *line, const char *token, const char **const return true; }
+static void parse_require_directive(struct shader_context *context, const char *line) +{ + if (match_string(line, "shader model >=", &line)) + { + static const char *const model_strings[] = + { + [SHADER_MODEL_4_0] = "4.0", + [SHADER_MODEL_4_1] = "4.1", + [SHADER_MODEL_5_0] = "5.0", + [SHADER_MODEL_5_1] = "5.1", + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(model_strings); ++i) + { + if (match_string(line, model_strings[i], &line)) + { + context->minimum_shader_model = i; + return; + } + } + + fatal_error("Unknown shader model '%s'.\n", line); + } + else + { + fatal_error("Unknown require directive '%s'.\n", line); + } +} + static void parse_texture_format(struct texture *texture, const char *line) { static const struct @@ -661,16 +701,27 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE: + case STATE_REQUIRE: case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break;
case STATE_SHADER_PIXEL: - if (!(context.ps_code = compile_shader(shader_source, "ps_4_0"))) + { + static const char *const shader_models[] = + { + [SHADER_MODEL_4_0] = "ps_4_0", + [SHADER_MODEL_4_1] = "ps_4_1", + [SHADER_MODEL_5_0] = "ps_5_0", + [SHADER_MODEL_5_1] = "ps_5_1", + }; + + if (!(context.ps_code = compile_shader(shader_source, shader_models[context.minimum_shader_model]))) return; shader_source_len = 0; break; + }
case STATE_SHADER_INVALID_PIXEL: { @@ -754,7 +805,11 @@ START_TEST(shader_runner_d3d12) { unsigned int index;
- if (!strcmp(line, "[pixel shader]\n")) + if (!strcmp(line, "[require]\n")) + { + state = STATE_REQUIRE; + } + else if (!strcmp(line, "[pixel shader]\n")) { state = STATE_SHADER_PIXEL;
@@ -843,6 +898,10 @@ START_TEST(shader_runner_d3d12) break; }
+ case STATE_REQUIRE: + parse_require_directive(&context, line); + break; + case STATE_SAMPLER: parse_sampler_directive(current_sampler, line); break;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
On 22/12/21 00:08, Zebediah Figura wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Split from the previous patch, add require directives to allow the tests to pass with native d3dcompiler.
Makefile.am | 3 + tests/hlsl-gather-offset.shader_test | 101 +++++++++++++++++++++++ tests/hlsl-gather.shader_test | 115 +++++++++++++++++++++++++++ tests/shader_runner_d3d12.c | 63 ++++++++++++++- 4 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 tests/hlsl-gather-offset.shader_test create mode 100644 tests/hlsl-gather.shader_test
diff --git a/Makefile.am b/Makefile.am index d0729681a..3aaa67b55 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,8 @@ vkd3d_shader_tests = \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \
- tests/hlsl-gather-offset.shader_test \
- tests/hlsl-gather.shader_test \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-invalid.shader_test \ tests/hlsl-majority-pragma.shader_test \
@@ -295,6 +297,7 @@ XFAIL_TESTS = \ tests/hlsl-duplicate-modifiers.shader_test \ tests/hlsl-for.shader_test \ tests/hlsl-function-overload.shader_test \
- tests/hlsl-gather.shader_test \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-majority-pragma.shader_test \ tests/hlsl-majority-typedef.shader_test \
diff --git a/tests/hlsl-gather-offset.shader_test b/tests/hlsl-gather-offset.shader_test new file mode 100644 index 000000000..51e6a6b64 --- /dev/null +++ b/tests/hlsl-gather-offset.shader_test @@ -0,0 +1,101 @@ +[require] +shader model >= 4.1
+[sampler 0] +filter linear linear linear +address clamp clamp clamp
+[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Gather(s, float2(0.2, 0.2), int2(1, 0));
+}
+[test] +draw quad +probe all rgba (0.1, 0.2, 0.2, 0.1)
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherRed(s, float2(0.6, 0.6), int2(-1, 0));
+}
+[test] +draw quad +probe all rgba (0.0, 0.1, 0.1, 0.0)
+[require] +shader model >= 5.0
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 1));
+}
+[test] +draw quad +probe all rgba (0.2, 0.2, 0.1, 0.1)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.8, 0.8), int2(-1, -1));
+}
+[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherBlue(s, float2(0.2, 0.8), int2(1, 0));
+}
+[test] +draw quad +probe all rgba (0.5, 0.0, 0.5, 0.0)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherAlpha(s, float2(0.2, 0.8), int2(0, -1));
+}
+[test] +draw quad +probe all rgba (0.0, 0.4, 0.0, 0.4) diff --git a/tests/hlsl-gather.shader_test b/tests/hlsl-gather.shader_test new file mode 100644 index 000000000..57af23d02 --- /dev/null +++ b/tests/hlsl-gather.shader_test @@ -0,0 +1,115 @@ +[require] +shader model >= 4.1
+[sampler 0] +filter linear linear linear +address clamp clamp clamp
+[texture 0] +size (3, 3) +0.0 0.0 0.0 0.4 0.1 0.0 0.5 0.0 0.2 0.0 0.0 0.4 +0.0 0.1 0.5 0.0 0.1 0.1 0.0 0.4 0.2 0.1 0.5 0.0 +0.0 0.2 0.0 0.4 0.1 0.2 0.5 0.0 0.2 0.2 0.0 0.4
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.Gather(s, float2(0.2, 0.2));
+}
+[test] +draw quad +probe all rgba (0.0, 0.1, 0.1, 0.0)
+[pixel shader] +sampler s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherRed(s, float2(0.6, 0.6), int2(0, 0));
+}
+[test] +draw quad +probe all rgba (0.1, 0.2, 0.2, 0.1)
+[require] +shader model >= 5.0
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 0));
+}
+[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.8, 0.8));
+}
+[test] +draw quad +probe all rgba (0.2, 0.2, 0.1, 0.1)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0));
+}
+[test] +draw quad +probe all rgba (0.1, 0.1, 0.0, 0.0)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherBlue(s, float2(0.2, 0.8), int2(0, 0));
+}
+[test] +draw quad +probe all rgba (0.0, 0.5, 0.0, 0.5)
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherAlpha(s, float2(0.2, 0.8), int2(0, 0));
+}
+[test] +draw quad +probe all rgba (0.4, 0.0, 0.4, 0.0) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index d404895fb..fa73b31b7 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -115,9 +115,18 @@ struct texture unsigned int root_index; };
+enum shader_model +{
- SHADER_MODEL_4_0 = 0,
- SHADER_MODEL_4_1,
- SHADER_MODEL_5_0,
- SHADER_MODEL_5_1,
+};
struct shader_context { struct test_context c;
enum shader_model minimum_shader_model;
ID3D10Blob *ps_code;
@@ -160,6 +169,7 @@ enum parse_state STATE_NONE, STATE_PREPROC, STATE_PREPROC_INVALID,
- STATE_REQUIRE, STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_PIXEL,
@@ -182,6 +192,36 @@ static bool match_string(const char *line, const char *token, const char **const return true; }
+static void parse_require_directive(struct shader_context *context, const char *line) +{
- if (match_string(line, "shader model >=", &line))
- {
static const char *const model_strings[] =
{
[SHADER_MODEL_4_0] = "4.0",
[SHADER_MODEL_4_1] = "4.1",
[SHADER_MODEL_5_0] = "5.0",
[SHADER_MODEL_5_1] = "5.1",
};
unsigned int i;
for (i = 0; i < ARRAY_SIZE(model_strings); ++i)
{
if (match_string(line, model_strings[i], &line))
{
context->minimum_shader_model = i;
return;
}
}
fatal_error("Unknown shader model '%s'.\n", line);
- }
- else
- {
fatal_error("Unknown require directive '%s'.\n", line);
- }
+}
- static void parse_texture_format(struct texture *texture, const char *line) { static const struct
@@ -661,16 +701,27 @@ START_TEST(shader_runner_d3d12) switch (state) { case STATE_NONE:
case STATE_REQUIRE: case STATE_SAMPLER: case STATE_TEST: case STATE_TEXTURE: break; case STATE_SHADER_PIXEL:
if (!(context.ps_code = compile_shader(shader_source, "ps_4_0")))
{
static const char *const shader_models[] =
{
[SHADER_MODEL_4_0] = "ps_4_0",
[SHADER_MODEL_4_1] = "ps_4_1",
[SHADER_MODEL_5_0] = "ps_5_0",
[SHADER_MODEL_5_1] = "ps_5_1",
};
if (!(context.ps_code = compile_shader(shader_source, shader_models[context.minimum_shader_model]))) return; shader_source_len = 0; break;
} case STATE_SHADER_INVALID_PIXEL: {
@@ -754,7 +805,11 @@ START_TEST(shader_runner_d3d12) { unsigned int index;
if (!strcmp(line, "[pixel shader]\n"))
if (!strcmp(line, "[require]\n"))
{
state = STATE_REQUIRE;
}
else if (!strcmp(line, "[pixel shader]\n")) { state = STATE_SHADER_PIXEL;
@@ -843,6 +898,10 @@ START_TEST(shader_runner_d3d12) break; }
case STATE_REQUIRE:
parse_require_directive(&context, line);
break;
case STATE_SAMPLER: parse_sampler_directive(current_sampler, line); break;
On Wed, Dec 22, 2021 at 12:23 AM Zebediah Figura zfigura@codeweavers.com wrote:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Split from the previous patch, add require directives to allow the tests to pass with native d3dcompiler.
Makefile.am | 3 + tests/hlsl-gather-offset.shader_test | 101 +++++++++++++++++++++++ tests/hlsl-gather.shader_test | 115 +++++++++++++++++++++++++++ tests/shader_runner_d3d12.c | 63 ++++++++++++++- 4 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 tests/hlsl-gather-offset.shader_test create mode 100644 tests/hlsl-gather.shader_test
diff --git a/tests/hlsl-gather.shader_test b/tests/hlsl-gather.shader_test new file mode 100644 index 000000000..57af23d02 --- /dev/null +++ b/tests/hlsl-gather.shader_test
+[pixel shader] +SamplerState s; +Texture2D t;
+float4 main() : sv_target +{
- return t.GatherGreen(s, float2(0.2, 0.2), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0));
+}
It might be interesting to add a test with multiple non-zero offsets.
Hi,
I think this patch and the following ones are fine, but I'd like to have my remaining copy propagation patches accepted before them, given that they have been in review for weeks and they are still waiting for reviewers' comments.
Unrelatedly, while reading this patch I noticed that hlsl_new_texture_type() allocates using vkd3d_calloc() instead of hlsl_alloc(). I guess that's an oversight, isn't it?
Giovanni.
On 22/12/21 00:08, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 3 ++ libs/vkd3d-shader/hlsl_codegen.c | 49 +++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d2ea4c34a..3a571b946 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -196,6 +196,8 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type }
case HLSL_CLASS_OBJECT:
/* For convenience when performing copy propagation. */
}type->reg_size = 1; break; }
@@ -273,6 +275,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ type->dimy = 1; type->sampler_dim = dim; type->e.resource_format = format;
- hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); return type; }
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e43e6378e..e426101fa 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -394,9 +394,26 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l struct hlsl_deref *src = &load->src; struct hlsl_ir_var *var = src->var; unsigned int offset, swizzle;
- unsigned int dimx = 0;
- if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR)
return false;
switch (type->type)
{
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
dimx = type->dimx;
break;
case HLSL_CLASS_OBJECT:
dimx = 1;
break;
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_ARRAY:
case HLSL_CLASS_STRUCT:
/* FIXME: Actually we shouldn't even get here, but we don't split
* matrices yet. */
return false;
}
if (!hlsl_offset_from_deref(src, &offset)) return false;
@@ -404,18 +421,22 @@ 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_replacement(var_def, offset, type->dimx, &swizzle)))
- if (!(new_node = copy_propagation_compute_replacement(var_def, offset, dimx, &swizzle))) {
TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + 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);
var->name, offset, offset + dimx, new_node, debug_hlsl_swizzle(swizzle, 4));
- if (type->type != HLSL_CLASS_OBJECT)
- {
if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, dimx, new_node, &node->loc)))
return false;
list_add_before(&node->entry, &swizzle_node->node.entry);
new_node = &swizzle_node->node;
- }
- replace_node(node, new_node); return true; }
@@ -431,9 +452,17 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s return;
if (hlsl_offset_from_deref(lhs, &offset))
copy_propagation_set_value(var_def, offset, store->writemask, store->rhs.node);
{
unsigned int writemask = store->writemask;
if (store->rhs.node->data_type->type == HLSL_CLASS_OBJECT)
writemask = VKD3DSP_WRITEMASK_0;
copy_propagation_set_value(var_def, offset, 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,