From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_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 8fc4e738..082c1c28 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); @@ -1621,12 +1624,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); @@ -1741,8 +1742,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);
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_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 082c1c28..714e237d 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); @@ -1649,7 +1649,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; @@ -1657,9 +1656,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: Henri Verbeet hverbeet@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_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 714e237d..3982a9b8 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); @@ -1653,7 +1659,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); @@ -1754,7 +1760,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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_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 3982a9b8..21d6c0d4 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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 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 d8913850..e46ddec0 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; }
@@ -1285,6 +1286,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, ")"); }
@@ -1458,6 +1464,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 6aec0b08..fffafb56 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -384,6 +384,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 @@ -708,7 +709,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 cff56a74..b4597e18 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 98afd0e0..eac3513c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1052,6 +1052,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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_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 21d6c0d4..8d42b9a3 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;
@@ -1741,6 +1775,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) @@ -1773,7 +1808,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 57633cd0..9cd26d7f 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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- 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 3b2e7d71..46f11072 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 \ @@ -306,6 +307,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 00000000..83900c55 --- /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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v6: Add an assert to dump_ir_resource_load(), make an assortment of small style tweaks.
libs/vkd3d-shader/hlsl.c | 5 ++ libs/vkd3d-shader/hlsl.h | 4 ++ libs/vkd3d-shader/hlsl.y | 100 +++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 57 +++++++++++++++++++- 4 files changed, 165 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e46ddec0..917c7bf7 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1278,8 +1278,13 @@ 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", };
+ assert(load->load_type < ARRAY_SIZE(type_names)); vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); dump_deref(buffer, &load->resource); vkd3d_string_buffer_printf(buffer, ", sampler = "); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index fffafb56..2319895a 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -376,6 +376,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 b4597e18..9476765f 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1930,6 +1930,106 @@ 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 status argument."); + + 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 1 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 %u 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 8d42b9a3..4eebd583 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]; @@ -1771,6 +1771,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) { @@ -1811,6 +1846,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: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- 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 46f11072..db0a6f68 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 \ @@ -294,6 +296,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 00000000..51e6a6b6 --- /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 00000000..57af23d0 --- /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 47f419b9..4a8d1f18 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 @@ -662,16 +702,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: { @@ -755,7 +806,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;
@@ -844,6 +899,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: Henri Verbeet hverbeet@codeweavers.com