wine-staging/patches/vkd3d-latest/0005-Updated-vkd3d-to-ab525f31e43a0f3c04c76b799aae88c1268.patch

1437 lines
58 KiB
Diff
Raw Normal View History

2024-09-20 16:44:13 -07:00
From 7158e5d2ecb970eb54299a2358f74ddae1248bc4 Mon Sep 17 00:00:00 2001
2024-09-11 16:00:19 -07:00
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 12 Sep 2024 08:58:41 +1000
Subject: [PATCH] Updated vkd3d to ab525f31e43a0f3c04c76b799aae88c12684b110.
---
libs/vkd3d/include/private/vkd3d_common.h | 2 +
libs/vkd3d/include/vkd3d_shader.h | 9 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 368 ++++--------------
libs/vkd3d/libs/vkd3d-shader/glsl.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 59 +--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 300 ++++++++++++++
libs/vkd3d/libs/vkd3d-shader/ir.c | 77 ++--
libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +-
libs/vkd3d/libs/vkd3d/command.c | 30 +-
libs/vkd3d/libs/vkd3d/device.c | 1 +
libs/vkd3d/libs/vkd3d/state.c | 1 +
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +-
14 files changed, 481 insertions(+), 378 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index c62dc00415f..fd62730f948 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -62,6 +62,8 @@
#define VKD3D_STRINGIFY(x) #x
#define VKD3D_EXPAND_AND_STRINGIFY(x) VKD3D_EXPAND(VKD3D_STRINGIFY(x))
+#define vkd3d_clamp(value, lower, upper) max(min(value, upper), lower)
+
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index d9a355d3bc9..5737d27c0e9 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -1292,7 +1292,8 @@ typedef int (*PFN_vkd3d_shader_open_include)(const char *filename, bool local,
* vkd3d_shader_preprocess_info.
*
* \param code Contents of the included file, which were allocated by the
- * \ref pfn_open_include callback. The user must free them.
+ * vkd3d_shader_preprocess_info.pfn_open_include callback.
+ * The user must free them.
*
* \param context The user-defined pointer passed to struct
* vkd3d_shader_preprocess_info.
@@ -1319,8 +1320,8 @@ struct vkd3d_shader_preprocess_info
/**
* Pointer to an array of predefined macros. Each macro in this array will
- * be expanded as if a corresponding #define statement were prepended to the
- * source code.
+ * be expanded as if a corresponding \#define statement were prepended to
+ * the source code.
*
* If the same macro is specified multiple times, only the last value is
* used.
@@ -2798,7 +2799,7 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_signature_info(struct vkd3d_shader_
* \param input_signature The input signature of the second shader.
*
* \param count On output, contains the number of entries written into
- * \ref varyings.
+ * "varyings".
*
* \param varyings Pointer to an output array of varyings.
* This must point to space for N varyings, where N is the number of elements
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index a41182e1f4a..e7d1d2420c6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1877,7 +1877,7 @@ struct sm1_instruction
struct sm1_dst_register
{
enum vkd3d_shader_register_type type;
- D3DSHADER_PARAM_DSTMOD_TYPE mod;
+ enum vkd3d_shader_dst_modifier mod;
unsigned int writemask;
uint32_t reg;
} dst;
@@ -1885,7 +1885,7 @@ struct sm1_instruction
struct sm1_src_register
{
enum vkd3d_shader_register_type type;
- D3DSHADER_PARAM_SRCMOD_TYPE mod;
+ enum vkd3d_shader_src_modifier mod;
unsigned int swizzle;
uint32_t reg;
} srcs[4];
@@ -1902,9 +1902,9 @@ static bool is_inconsequential_instr(const struct sm1_instruction *instr)
if (instr->opcode != VKD3D_SM1_OP_MOV)
return false;
- if (dst->mod != D3DSPDM_NONE)
+ if (dst->mod != VKD3DSPDM_NONE)
return false;
- if (src->mod != D3DSPSM_NONE)
+ if (src->mod != VKD3DSPSM_NONE)
return false;
if (src->type != dst->type)
return false;
@@ -1923,13 +1923,19 @@ static bool is_inconsequential_instr(const struct sm1_instruction *instr)
static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_dst_register *reg)
{
VKD3D_ASSERT(reg->writemask);
- put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg);
+ put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER
+ | sm1_encode_register_type(reg->type)
+ | (reg->mod << VKD3D_SM1_DST_MODIFIER_SHIFT)
+ | (reg->writemask << VKD3D_SM1_WRITEMASK_SHIFT) | reg->reg);
}
static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer,
const struct sm1_src_register *reg)
{
- put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->swizzle << 16) | reg->reg);
+ put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER
+ | sm1_encode_register_type(reg->type)
+ | (reg->mod << VKD3D_SM1_SRC_MODIFIER_SHIFT)
+ | (reg->swizzle << VKD3D_SM1_SWIZZLE_SHIFT) | reg->reg);
}
static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct sm1_instruction *instr)
@@ -1960,117 +1966,9 @@ static void sm1_map_src_swizzle(struct sm1_src_register *src, unsigned int map_w
src->swizzle = hlsl_map_swizzle(src->swizzle, map_writemask);
}
-static void d3dbc_write_dp2add(struct d3dbc_compiler *d3dbc, const struct hlsl_reg *dst,
- const struct hlsl_reg *src1, const struct hlsl_reg *src2, const struct hlsl_reg *src3)
-{
- struct sm1_instruction instr =
- {
- .opcode = VKD3D_SM1_OP_DP2ADD,
-
- .dst.type = VKD3DSPR_TEMP,
- .dst.writemask = dst->writemask,
- .dst.reg = dst->id,
- .has_dst = 1,
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask),
- .srcs[0].reg = src1->id,
- .srcs[1].type = VKD3DSPR_TEMP,
- .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask),
- .srcs[1].reg = src2->id,
- .srcs[2].type = VKD3DSPR_TEMP,
- .srcs[2].swizzle = hlsl_swizzle_from_writemask(src3->writemask),
- .srcs[2].reg = src3->id,
- .src_count = 3,
- };
-
- d3dbc_write_instruction(d3dbc, &instr);
-}
-
-static void d3dbc_write_ternary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode,
- const struct hlsl_reg *dst, const struct hlsl_reg *src1,
- const struct hlsl_reg *src2, const struct hlsl_reg *src3)
-{
- struct sm1_instruction instr =
- {
- .opcode = opcode,
-
- .dst.type = VKD3DSPR_TEMP,
- .dst.writemask = dst->writemask,
- .dst.reg = dst->id,
- .has_dst = 1,
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask),
- .srcs[0].reg = src1->id,
- .srcs[1].type = VKD3DSPR_TEMP,
- .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask),
- .srcs[1].reg = src2->id,
- .srcs[2].type = VKD3DSPR_TEMP,
- .srcs[2].swizzle = hlsl_swizzle_from_writemask(src3->writemask),
- .srcs[2].reg = src3->id,
- .src_count = 3,
- };
-
- sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask);
- sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask);
- sm1_map_src_swizzle(&instr.srcs[2], instr.dst.writemask);
- d3dbc_write_instruction(d3dbc, &instr);
-}
-
-static void d3dbc_write_binary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode,
- const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2)
-{
- struct sm1_instruction instr =
- {
- .opcode = opcode,
-
- .dst.type = VKD3DSPR_TEMP,
- .dst.writemask = dst->writemask,
- .dst.reg = dst->id,
- .has_dst = 1,
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask),
- .srcs[0].reg = src1->id,
- .srcs[1].type = VKD3DSPR_TEMP,
- .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask),
- .srcs[1].reg = src2->id,
- .src_count = 2,
- };
-
- sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask);
- sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask);
- d3dbc_write_instruction(d3dbc, &instr);
-}
-
-static void d3dbc_write_dot(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode,
- const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2)
-{
- struct sm1_instruction instr =
- {
- .opcode = opcode,
-
- .dst.type = VKD3DSPR_TEMP,
- .dst.writemask = dst->writemask,
- .dst.reg = dst->id,
- .has_dst = 1,
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask),
- .srcs[0].reg = src1->id,
- .srcs[1].type = VKD3DSPR_TEMP,
- .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask),
- .srcs[1].reg = src2->id,
- .src_count = 2,
- };
-
- d3dbc_write_instruction(d3dbc, &instr);
-}
-
static void d3dbc_write_unary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode,
const struct hlsl_reg *dst, const struct hlsl_reg *src,
- D3DSHADER_PARAM_SRCMOD_TYPE src_mod, D3DSHADER_PARAM_DSTMOD_TYPE dst_mod)
+ enum vkd3d_shader_src_modifier src_mod, enum vkd3d_shader_dst_modifier dst_mod)
{
struct sm1_instruction instr =
{
@@ -2209,7 +2107,7 @@ static uint32_t swizzle_from_vsir(uint32_t swizzle)
static void sm1_src_reg_from_vsir(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_src_param *param,
struct sm1_src_register *src, const struct vkd3d_shader_location *loc)
{
- src->mod = (uint32_t)param->modifiers << VKD3D_SM1_SRC_MODIFIER_SHIFT;
+ src->mod = param->modifiers;
src->reg = param->reg.idx[0].offset;
src->type = param->reg.type;
src->swizzle = swizzle_from_vsir(param->swizzle);
@@ -2225,7 +2123,7 @@ static void sm1_src_reg_from_vsir(struct d3dbc_compiler *d3dbc, const struct vkd
static void sm1_dst_reg_from_vsir(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_dst_param *param,
struct sm1_dst_register *dst, const struct vkd3d_shader_location *loc)
{
- dst->mod = (uint32_t)param->modifiers << VKD3D_SM1_DST_MODIFIER_SHIFT;
+ dst->mod = param->modifiers;
dst->reg = param->reg.idx[0].offset;
dst->type = param->reg.type;
dst->writemask = param->write_mask;
@@ -2326,13 +2224,18 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3
}
}
-static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
- const struct vkd3d_shader_instruction *ins)
+static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_instruction(
+ struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
{
const struct vkd3d_sm1_opcode_info *info;
- struct sm1_instruction instr = {0};
- info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode);
+ if (!(info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode)))
+ {
+ vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
+ "Opcode %#x not supported for shader profile.", ins->opcode);
+ d3dbc->failed = true;
+ return NULL;
+ }
if (ins->dst_count != info->dst_count)
{
@@ -2340,7 +2243,7 @@ static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
"Invalid destination count %u for vsir instruction %#x (expected %u).",
ins->dst_count, ins->opcode, info->dst_count);
d3dbc->failed = true;
- return;
+ return NULL;
}
if (ins->src_count != info->src_count)
{
@@ -2348,9 +2251,21 @@ static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
"Invalid source count %u for vsir instruction %#x (expected %u).",
ins->src_count, ins->opcode, info->src_count);
d3dbc->failed = true;
- return;
+ return NULL;
}
+ return info;
+}
+
+static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
+ const struct vkd3d_shader_instruction *ins)
+{
+ struct sm1_instruction instr = {0};
+ const struct vkd3d_sm1_opcode_info *info;
+
+ if (!(info = shader_sm1_get_opcode_info_from_vsir_instruction(d3dbc, ins)))
+ return;
+
instr.opcode = info->sm1_opcode;
instr.has_dst = info->dst_count;
instr.src_count = info->src_count;
@@ -2365,6 +2280,8 @@ static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
{
+ uint32_t writemask;
+
switch (ins->opcode)
{
case VKD3DSIH_DEF:
@@ -2375,7 +2292,39 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
d3dbc_write_vsir_dcl(d3dbc, ins);
break;
+ case VKD3DSIH_ABS:
+ case VKD3DSIH_ADD:
+ case VKD3DSIH_CMP:
+ case VKD3DSIH_DP2ADD:
+ case VKD3DSIH_DP3:
+ case VKD3DSIH_DP4:
+ case VKD3DSIH_DSX:
+ case VKD3DSIH_DSY:
+ case VKD3DSIH_FRC:
+ case VKD3DSIH_MAD:
+ case VKD3DSIH_MAX:
+ case VKD3DSIH_MIN:
case VKD3DSIH_MOV:
+ case VKD3DSIH_MUL:
+ case VKD3DSIH_SINCOS:
+ case VKD3DSIH_SLT:
+ d3dbc_write_vsir_simple_instruction(d3dbc, ins);
+ break;
+
+ case VKD3DSIH_EXP:
+ case VKD3DSIH_LOG:
+ case VKD3DSIH_RCP:
+ case VKD3DSIH_RSQ:
+ writemask = ins->dst->write_mask;
+ if (writemask != VKD3DSP_WRITEMASK_0 && writemask != VKD3DSP_WRITEMASK_1
+ && writemask != VKD3DSP_WRITEMASK_2 && writemask != VKD3DSP_WRITEMASK_3)
+ {
+ vkd3d_shader_error(d3dbc->message_context, &ins->location,
+ VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK,
+ "writemask %#x for vsir instruction with opcode %#x is not single component.",
+ writemask, ins->opcode);
+ d3dbc->failed = true;
+ }
d3dbc_write_vsir_simple_instruction(d3dbc, ins);
break;
@@ -2452,69 +2401,10 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc)
}
}
-static void d3dbc_write_per_component_unary_op(struct d3dbc_compiler *d3dbc,
- const struct hlsl_ir_node *instr, enum vkd3d_sm1_opcode opcode)
-{
- struct hlsl_ir_expr *expr = hlsl_ir_expr(instr);
- struct hlsl_ir_node *arg1 = expr->operands[0].node;
- unsigned int i;
-
- for (i = 0; i < instr->data_type->dimx; ++i)
- {
- struct hlsl_reg src = arg1->reg, dst = instr->reg;
-
- src.writemask = hlsl_combine_writemasks(src.writemask, 1u << i);
- dst.writemask = hlsl_combine_writemasks(dst.writemask, 1u << i);
- d3dbc_write_unary_op(d3dbc, opcode, &dst, &src, 0, 0);
- }
-}
-
-static void d3dbc_write_sincos(struct d3dbc_compiler *d3dbc, enum hlsl_ir_expr_op op,
- const struct hlsl_reg *dst, const struct hlsl_reg *src)
-{
- struct sm1_instruction instr =
- {
- .opcode = VKD3D_SM1_OP_SINCOS,
-
- .dst.type = VKD3DSPR_TEMP,
- .dst.writemask = dst->writemask,
- .dst.reg = dst->id,
- .has_dst = 1,
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(src->writemask),
- .srcs[0].reg = src->id,
- .src_count = 1,
- };
-
- if (op == HLSL_OP1_COS_REDUCED)
- VKD3D_ASSERT(dst->writemask == VKD3DSP_WRITEMASK_0);
- else /* HLSL_OP1_SIN_REDUCED */
- VKD3D_ASSERT(dst->writemask == VKD3DSP_WRITEMASK_1);
-
- if (d3dbc->ctx->profile->major_version < 3)
- {
- instr.src_count = 3;
-
- instr.srcs[1].type = VKD3DSPR_CONST;
- instr.srcs[1].swizzle = hlsl_swizzle_from_writemask(VKD3DSP_WRITEMASK_ALL);
- instr.srcs[1].reg = d3dbc->ctx->d3dsincosconst1.id;
-
- instr.srcs[2].type = VKD3DSPR_CONST;
- instr.srcs[2].swizzle = hlsl_swizzle_from_writemask(VKD3DSP_WRITEMASK_ALL);
- instr.srcs[2].reg = d3dbc->ctx->d3dsincosconst2.id;
- }
-
- d3dbc_write_instruction(d3dbc, &instr);
-}
-
static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_node *instr)
{
- const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
struct hlsl_ir_expr *expr = hlsl_ir_expr(instr);
struct hlsl_ir_node *arg1 = expr->operands[0].node;
- struct hlsl_ir_node *arg2 = expr->operands[1].node;
- struct hlsl_ir_node *arg3 = expr->operands[2].node;
struct hlsl_ctx *ctx = d3dbc->ctx;
VKD3D_ASSERT(instr->reg.allocated);
@@ -2538,117 +2428,7 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_
return;
}
- switch (expr->op)
- {
- case HLSL_OP1_ABS:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_ABS, &instr->reg, &arg1->reg, 0, 0);
- break;
-
- case HLSL_OP1_DSX:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_DSX, &instr->reg, &arg1->reg, 0, 0);
- break;
-
- case HLSL_OP1_DSY:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_DSY, &instr->reg, &arg1->reg, 0, 0);
- break;
-
- case HLSL_OP1_EXP2:
- d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_EXP);
- break;
-
- case HLSL_OP1_LOG2:
- d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_LOG);
- break;
-
- case HLSL_OP1_NEG:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG, 0);
- break;
-
- case HLSL_OP1_SAT:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, 0, D3DSPDM_SATURATE);
- break;
-
- case HLSL_OP1_RCP:
- d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_RCP);
- break;
-
- case HLSL_OP1_RSQ:
- d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_RSQ);
- break;
-
- case HLSL_OP1_COS_REDUCED:
- case HLSL_OP1_SIN_REDUCED:
- d3dbc_write_sincos(d3dbc, expr->op, &instr->reg, &arg1->reg);
- break;
-
- case HLSL_OP2_ADD:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_ADD, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP2_MAX:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MAX, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP2_MIN:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MIN, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP2_MUL:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MUL, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP1_FRACT:
- d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_FRC, &instr->reg, &arg1->reg, D3DSPSM_NONE, 0);
- break;
-
- case HLSL_OP2_DOT:
- switch (arg1->data_type->dimx)
- {
- case 4:
- d3dbc_write_dot(d3dbc, VKD3D_SM1_OP_DP4, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case 3:
- d3dbc_write_dot(d3dbc, VKD3D_SM1_OP_DP3, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- default:
- vkd3d_unreachable();
- }
- break;
-
- case HLSL_OP2_LOGIC_AND:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MIN, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP2_LOGIC_OR:
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MAX, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP2_SLT:
- if (version->type == VKD3D_SHADER_TYPE_PIXEL)
- hlsl_fixme(ctx, &instr->loc, "Lower SLT instructions for pixel shaders.");
- d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_SLT, &instr->reg, &arg1->reg, &arg2->reg);
- break;
-
- case HLSL_OP3_CMP:
- if (version->type == VKD3D_SHADER_TYPE_VERTEX)
- hlsl_fixme(ctx, &instr->loc, "Lower CMP instructions for vertex shaders.");
- d3dbc_write_ternary_op(d3dbc, VKD3D_SM1_OP_CMP, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg);
- break;
-
- case HLSL_OP3_DP2ADD:
- d3dbc_write_dp2add(d3dbc, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg);
- break;
-
- case HLSL_OP3_MAD:
- d3dbc_write_ternary_op(d3dbc, VKD3D_SM1_OP_MAD, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg);
- break;
-
- default:
- hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op));
- break;
- }
+ hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op));
}
static void d3dbc_write_block(struct d3dbc_compiler *d3dbc, const struct hlsl_block *block);
@@ -2675,7 +2455,7 @@ static void d3dbc_write_if(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_no
.srcs[1].type = VKD3DSPR_TEMP,
.srcs[1].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
.srcs[1].reg = condition->reg.id,
- .srcs[1].mod = D3DSPSM_NEG,
+ .srcs[1].mod = VKD3DSPSM_NEG,
.src_count = 2,
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index d1f02ab568b..b0aacdfef65 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -311,7 +311,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags,
struct vkd3d_glsl_generator generator;
int ret;
- if ((ret = vsir_program_normalise(program, config_flags, compile_info, message_context)) < 0)
+ if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
vkd3d_glsl_generator_init(&generator, program, message_context);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 9bcba99efff..bdd0e401770 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -715,7 +715,7 @@ enum hlsl_ir_expr_op
HLSL_OP2_SLT,
/* DP2ADD(a, b, c) computes the scalar product of a.xy and b.xy,
- * then adds c. */
+ * then adds c, where c must have dimx=1. */
HLSL_OP3_DP2ADD,
/* TERNARY(a, b, c) returns 'b' if 'a' is true and 'c' otherwise. 'a' must always be boolean.
* CMP(a, b, c) returns 'b' if 'a' >= 0, and 'c' otherwise. It's used only for SM1-SM3 targets. */
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 38642025b52..eabf072befb 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -3309,9 +3309,9 @@ static bool write_atan_or_atan2(struct hlsl_ctx *ctx,
" : poly_approx;\n"
"}";
- if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc)))
+ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
return false;
- type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
+ type = params->args[0]->data_type;
if (!(buf = hlsl_get_string_buffer(ctx)))
return false;
@@ -3809,7 +3809,7 @@ static bool intrinsic_dst(struct hlsl_ctx *ctx, const struct parse_initializer *
" return %s(1, src0.y * src1.y, src0.z, src1.w);\n"
"}";
- if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
+ if (!elementwise_intrinsic_convert_args(ctx, params, loc))
return false;
type = params->args[0]->data_type;
if (!(type->class == HLSL_CLASS_SCALAR
@@ -3880,9 +3880,9 @@ static bool intrinsic_faceforward(struct hlsl_ctx *ctx,
" return dot(i, ng) < 0 ? n : -n;\n"
"}\n";
- if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc)))
+ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
return false;
- type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
+ type = params->args[0]->data_type;
if (!(body = hlsl_sprintf_alloc(ctx, template,
type->name, type->name, type->name, type->name)))
@@ -4370,13 +4370,9 @@ static bool intrinsic_reflect(struct hlsl_ctx *ctx,
static bool intrinsic_refract(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
- struct hlsl_type *r_type = params->args[0]->data_type;
- struct hlsl_type *n_type = params->args[1]->data_type;
- struct hlsl_type *i_type = params->args[2]->data_type;
- struct hlsl_type *res_type, *idx_type, *scal_type;
- struct parse_initializer mut_params;
+ struct hlsl_type *type, *scalar_type;
struct hlsl_ir_function_decl *func;
- enum hlsl_base_type base;
+ struct hlsl_ir_node *index;
char *body;
static const char template[] =
@@ -4388,28 +4384,34 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx,
" return t >= 0.0 ? i.x * r - (i.x * d + sqrt(t)) * n : 0;\n"
"}";
- if (r_type->class == HLSL_CLASS_MATRIX
- || n_type->class == HLSL_CLASS_MATRIX
- || i_type->class == HLSL_CLASS_MATRIX)
+ if (params->args[0]->data_type->class == HLSL_CLASS_MATRIX
+ || params->args[1]->data_type->class == HLSL_CLASS_MATRIX
+ || params->args[2]->data_type->class == HLSL_CLASS_MATRIX)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Matrix arguments are not supported.");
return false;
}
- VKD3D_ASSERT(params->args_count == 3);
- mut_params = *params;
- mut_params.args_count = 2;
- if (!(res_type = elementwise_intrinsic_get_common_type(ctx, &mut_params, loc)))
+ /* This is technically not an elementwise intrinsic, but the first two
+ * arguments are.
+ * The third argument is a scalar, but can be passed as a vector,
+ * which should generate an implicit truncation warning.
+ * Cast down to scalar explicitly, then we can just use
+ * elementwise_intrinsic_float_convert_args().
+ * This may result in casting the scalar back to a vector,
+ * which we will only use the first component of. */
+
+ scalar_type = hlsl_get_scalar_type(ctx, params->args[2]->data_type->e.numeric.type);
+ if (!(index = add_implicit_conversion(ctx, params->instrs, params->args[2], scalar_type, loc)))
return false;
+ params->args[2] = index;
- base = expr_common_base_type(res_type->e.numeric.type, i_type->e.numeric.type);
- base = base == HLSL_TYPE_HALF ? HLSL_TYPE_HALF : HLSL_TYPE_FLOAT;
- res_type = convert_numeric_type(ctx, res_type, base);
- idx_type = convert_numeric_type(ctx, i_type, base);
- scal_type = hlsl_get_scalar_type(ctx, base);
+ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
+ return false;
+ type = params->args[0]->data_type;
- if (!(body = hlsl_sprintf_alloc(ctx, template, res_type->name, res_type->name,
- res_type->name, idx_type->name, scal_type->name)))
+ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name,
+ type->name, type->name, scalar_type->name)))
return false;
func = hlsl_compile_internal_function(ctx, "refract", body);
@@ -4550,9 +4552,9 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx,
" return (p * p) * (3 - 2 * p);\n"
"}";
- if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc)))
+ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
return false;
- type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
+ type = params->args[0]->data_type;
if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, type->name, type->name)))
return false;
@@ -4583,13 +4585,12 @@ static bool intrinsic_step(struct hlsl_ctx *ctx,
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
return false;
+ type = params->args[0]->data_type;
if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL,
params->args[1], params->args[0], loc)))
return false;
- type = ge->data_type;
- type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index e470115f191..2d80b524913 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -6506,6 +6506,303 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
hlsl_replace_node(instr, vsir_instr);
}
+/* Translate ops that can be mapped to a single vsir instruction with only one dst register. */
+static void sm1_generate_vsir_instr_expr_single_instr_op(struct hlsl_ctx *ctx, struct vsir_program *program,
+ struct hlsl_ir_expr *expr, enum vkd3d_shader_opcode opcode, uint32_t src_mod, uint32_t dst_mod,
+ bool map_src_swizzles)
+{
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ struct hlsl_ir_node *instr = &expr->node;
+ struct vkd3d_shader_dst_param *dst_param;
+ struct vkd3d_shader_src_param *src_param;
+ struct vkd3d_shader_instruction *ins;
+ struct hlsl_ir_node *vsir_instr;
+ unsigned int i, src_count = 0;
+
+ VKD3D_ASSERT(instr->reg.allocated);
+
+ for (i = 0; i < HLSL_MAX_OPERANDS; ++i)
+ {
+ if (expr->operands[i].node)
+ src_count = i + 1;
+ }
+ VKD3D_ASSERT(!src_mod || src_count == 1);
+
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, src_count)))
+ return;
+
+ dst_param = &ins->dst[0];
+ vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ dst_param->reg.idx[0].offset = instr->reg.id;
+ dst_param->write_mask = instr->reg.writemask;
+ dst_param->modifiers = dst_mod;
+
+ for (i = 0; i < src_count; ++i)
+ {
+ struct hlsl_ir_node *operand = expr->operands[i].node;
+
+ src_param = &ins->src[i];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = operand->reg.id;
+ src_param->swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask,
+ map_src_swizzles ? dst_param->write_mask : VKD3DSP_WRITEMASK_ALL);
+ src_param->modifiers = src_mod;
+ }
+
+ if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, instr->data_type,
+ &instr->reg, &instr->loc)))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ return;
+ }
+
+ list_add_before(&instr->entry, &vsir_instr->entry);
+ hlsl_replace_node(instr, vsir_instr);
+}
+
+/* Translate ops that have 1 src and need one instruction for each component in
+ * the d3dbc backend. */
+static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx *ctx,
+ struct vsir_program *program, struct hlsl_ir_expr *expr, enum vkd3d_shader_opcode opcode)
+{
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ struct hlsl_ir_node *operand = expr->operands[0].node;
+ struct hlsl_ir_node *instr = &expr->node;
+ struct vkd3d_shader_dst_param *dst_param;
+ struct vkd3d_shader_src_param *src_param;
+ struct hlsl_ir_node *vsir_instr = NULL;
+ struct vkd3d_shader_instruction *ins;
+ uint32_t src_swizzle;
+ unsigned int i, c;
+
+ VKD3D_ASSERT(instr->reg.allocated);
+ VKD3D_ASSERT(operand);
+
+ src_swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask, instr->reg.writemask);
+ for (i = 0; i < 4; ++i)
+ {
+ if (instr->reg.writemask & (1u << i))
+ {
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 1)))
+ return;
+
+ dst_param = &ins->dst[0];
+ vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ dst_param->reg.idx[0].offset = instr->reg.id;
+ dst_param->write_mask = 1u << i;
+
+ src_param = &ins->src[0];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = operand->reg.id;
+ c = vsir_swizzle_get_component(src_swizzle, i);
+ src_param->swizzle = vsir_swizzle_from_writemask(1u << c);
+
+ if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1,
+ hlsl_get_scalar_type(ctx, instr->data_type->e.numeric.type),
+ &instr->reg, &instr->loc)))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ return;
+ }
+ list_add_before(&instr->entry, &vsir_instr->entry);
+ }
+ }
+
+ /* Replace expr with a no-op move. For the other instructions that reference it. */
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ return;
+
+ dst_param = &ins->dst[0];
+ vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ dst_param->reg.idx[0].offset = instr->reg.id;
+ dst_param->write_mask = instr->reg.writemask;
+
+ src_param = &ins->src[0];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = instr->reg.id;
+ src_param->swizzle = sm1_generate_vsir_get_src_swizzle(instr->reg.writemask, dst_param->write_mask);
+
+ if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, instr->data_type,
+ &instr->reg, &instr->loc)))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ return;
+ }
+ list_add_before(&instr->entry, &vsir_instr->entry);
+ hlsl_replace_node(instr, vsir_instr);
+}
+
+static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsir_program *program,
+ struct hlsl_ir_expr *expr)
+{
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ struct hlsl_ir_node *operand = expr->operands[0].node;
+ struct hlsl_ir_node *instr = &expr->node;
+ struct vkd3d_shader_dst_param *dst_param;
+ struct vkd3d_shader_src_param *src_param;
+ struct vkd3d_shader_instruction *ins;
+ struct hlsl_ir_node *vsir_instr;
+ unsigned int src_count = 0;
+
+ VKD3D_ASSERT(instr->reg.allocated);
+ src_count = (ctx->profile->major_version < 3) ? 3 : 1;
+
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count)))
+ return;
+
+ dst_param = &ins->dst[0];
+ vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ dst_param->reg.idx[0].offset = instr->reg.id;
+ dst_param->write_mask = instr->reg.writemask;
+
+ src_param = &ins->src[0];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = operand->reg.id;
+ src_param->swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask, VKD3DSP_WRITEMASK_ALL);
+
+ if (ctx->profile->major_version < 3)
+ {
+ src_param = &ins->src[1];
+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id;
+ src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+
+ src_param = &ins->src[1];
+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id;
+ src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ }
+
+ if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, instr->data_type,
+ &instr->reg, &instr->loc)))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ return;
+ }
+
+ list_add_before(&instr->entry, &vsir_instr->entry);
+ hlsl_replace_node(instr, vsir_instr);
+}
+
+static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_program *program,
+ struct hlsl_ir_expr *expr)
+{
+ switch (expr->op)
+ {
+ case HLSL_OP1_ABS:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ABS, 0, 0, true);
+ break;
+
+ case HLSL_OP1_COS_REDUCED:
+ VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_0);
+ sm1_generate_vsir_instr_expr_sincos(ctx, program, expr);
+ break;
+
+ case HLSL_OP1_DSX:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true);
+ break;
+
+ case HLSL_OP1_DSY:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true);
+ break;
+
+ case HLSL_OP1_EXP2:
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP);
+ break;
+
+ case HLSL_OP1_LOG2:
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG);
+ break;
+
+ case HLSL_OP1_NEG:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true);
+ break;
+
+ case HLSL_OP1_RCP:
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP);
+ break;
+
+ case HLSL_OP1_RSQ:
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ);
+ break;
+
+ case HLSL_OP1_SAT:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true);
+ break;
+
+ case HLSL_OP1_SIN_REDUCED:
+ VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_1);
+ sm1_generate_vsir_instr_expr_sincos(ctx, program, expr);
+ break;
+
+ case HLSL_OP2_ADD:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true);
+ break;
+
+ case HLSL_OP2_DOT:
+ switch (expr->operands[0].node->data_type->dimx)
+ {
+ case 3:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false);
+ break;
+
+ case 4:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false);
+ break;
+
+ default:
+ vkd3d_unreachable();
+ return false;
+ }
+ break;
+
+ case HLSL_OP2_MAX:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true);
+ break;
+
+ case HLSL_OP2_MIN:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true);
+ break;
+
+ case HLSL_OP2_MUL:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true);
+ break;
+
+ case HLSL_OP1_FRACT:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true);
+ break;
+
+ case HLSL_OP2_LOGIC_AND:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true);
+ break;
+
+ case HLSL_OP2_LOGIC_OR:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true);
+ break;
+
+ case HLSL_OP2_SLT:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true);
+ break;
+
+ case HLSL_OP3_CMP:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true);
+ break;
+
+ case HLSL_OP3_DP2ADD:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false);
+ break;
+
+ case HLSL_OP3_MAD:
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true);
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx,
struct vkd3d_shader_dst_param *dst_param, struct hlsl_deref *deref,
const struct vkd3d_shader_location *loc, unsigned int writemask)
@@ -6709,6 +7006,9 @@ static bool sm1_generate_vsir_instr(struct hlsl_ctx *ctx, struct hlsl_ir_node *i
sm1_generate_vsir_instr_constant(ctx, program, hlsl_ir_constant(instr));
return true;
+ case HLSL_IR_EXPR:
+ return sm1_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr));
+
case HLSL_IR_LOAD:
sm1_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr));
return true;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 68f2e2f795e..6cef85fdc84 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -19,7 +19,7 @@
#include "vkd3d_shader_private.h"
#include "vkd3d_types.h"
-struct vsir_normalisation_context
+struct vsir_transformation_context
{
enum vkd3d_result result;
struct vsir_program *program;
@@ -451,7 +451,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog
}
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct vkd3d_shader_message_context *message_context = ctx->message_context;
@@ -551,7 +551,7 @@ static const struct vkd3d_shader_varying_map *find_varying_map(
}
static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name};
struct vkd3d_shader_message_context *message_context = ctx->message_context;
@@ -865,7 +865,7 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
}
static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct hull_flattener flattener = {program->instructions};
struct vkd3d_shader_instruction_array *instructions;
@@ -1004,7 +1004,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
}
static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(
- struct vsir_program *program, struct vsir_normalisation_context *ctx)
+ struct vsir_program *program, struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_instruction_array *instructions;
struct control_point_normaliser normaliser;
@@ -1772,7 +1772,7 @@ static bool use_flat_interpolation(const struct vsir_program *program,
}
static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_message_context *message_context = ctx->message_context;
struct io_normaliser normaliser = {program->instructions};
@@ -1922,7 +1922,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
}
static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct flat_constants_normaliser normaliser = {0};
unsigned int i, j;
@@ -1961,7 +1961,8 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
return VKD3D_OK;
}
-static void remove_dead_code(struct vsir_program *program)
+static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
{
size_t i, depth = 0;
bool dead = false;
@@ -2049,10 +2050,12 @@ static void remove_dead_code(struct vsir_program *program)
break;
}
}
+
+ return VKD3D_OK;
}
static enum vkd3d_result vsir_program_normalise_combined_samplers(struct vsir_program *program,
- struct vkd3d_shader_message_context *message_context)
+ struct vsir_transformation_context *ctx)
{
unsigned int i;
@@ -2137,7 +2140,8 @@ static enum vkd3d_result vsir_program_normalise_combined_samplers(struct vsir_pr
case VKD3DSIH_TEXREG2AR:
case VKD3DSIH_TEXREG2GB:
case VKD3DSIH_TEXREG2RGB:
- vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ vkd3d_shader_error(ctx->message_context, &ins->location,
+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
"Aborting due to not yet implemented feature: "
"Combined sampler instruction %#x.", ins->opcode);
return VKD3D_ERROR_NOT_IMPLEMENTED;
@@ -2793,7 +2797,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
}
static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_message_context *message_context = ctx->message_context;
struct cf_flattener flattener = {.program = program};
@@ -2866,7 +2870,7 @@ static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_i
}
static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label;
size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0;
@@ -3057,7 +3061,7 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl
}
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i;
struct ssas_to_temps_block_info *info, *block_info = NULL;
@@ -5278,7 +5282,7 @@ out:
}
static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_message_context *message_context = ctx->message_context;
struct vsir_cfg_emit_target target = {0};
@@ -5459,7 +5463,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f
}
static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program,
- struct vsir_normalisation_context *ctx)
+ struct vsir_transformation_context *ctx)
{
struct vkd3d_shader_message_context *message_context = ctx->message_context;
enum vkd3d_result ret;
@@ -5605,8 +5609,9 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
}
static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program,
- struct vkd3d_shader_message_context *message_context)
+ struct vsir_transformation_context *ctx)
{
+ struct vkd3d_shader_message_context *message_context = ctx->message_context;
const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL;
static const struct vkd3d_shader_location no_loc;
enum vkd3d_shader_comparison_func compare_func;
@@ -6622,30 +6627,30 @@ fail:
#define vsir_transform(ctx, step) vsir_transform_(ctx, #step, step)
static void vsir_transform_(
- struct vsir_normalisation_context *ctx, const char *step_name,
- enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_normalisation_context *ctx))
+ struct vsir_transformation_context *ctx, const char *step_name,
+ enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_transformation_context *ctx))
{
if (ctx->result < 0)
return;
if ((ctx->result = step(ctx->program, ctx)) < 0)
{
- WARN("Transformation \"%s\" failed with result %u.\n", step_name, ctx->result);
+ WARN("Transformation \"%s\" failed with result %d.\n", step_name, ctx->result);
return;
}
if ((ctx->result = vsir_program_validate(ctx->program, ctx->config_flags,
ctx->compile_info->source_name, ctx->message_context)) < 0)
{
- WARN("Validation failed with result %u after transformation \"%s\".\n", ctx->result, step_name);
+ WARN("Validation failed with result %d after transformation \"%s\".\n", ctx->result, step_name);
return;
}
}
-enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags,
+enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{
- struct vsir_normalisation_context ctx =
+ struct vsir_transformation_context ctx =
{
.result = VKD3D_OK,
.program = program,
@@ -6653,7 +6658,6 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
.compile_info = compile_info,
.message_context = message_context,
};
- enum vkd3d_result result;
vsir_transform(&ctx, vsir_program_lower_instructions);
@@ -6664,9 +6668,6 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
vsir_transform(&ctx, vsir_program_structurize);
vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs);
vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps);
-
- if (ctx.result < 0)
- return ctx.result;
}
else
{
@@ -6681,29 +6682,17 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
vsir_transform(&ctx, vsir_program_normalise_io_registers);
vsir_transform(&ctx, vsir_program_normalise_flat_constants);
+ vsir_transform(&ctx, vsir_program_remove_dead_code);
+ vsir_transform(&ctx, vsir_program_normalise_combined_samplers);
- if (ctx.result < 0)
- return ctx.result;
-
- remove_dead_code(program);
-
- if ((result = vsir_program_normalise_combined_samplers(program, message_context)) < 0)
- return result;
-
- if (compile_info->target_type != VKD3D_SHADER_TARGET_GLSL
- && (result = vsir_program_flatten_control_flow_constructs(program, &ctx)) < 0)
- return result;
+ if (compile_info->target_type != VKD3D_SHADER_TARGET_GLSL)
+ vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs);
}
- if ((result = vsir_program_insert_alpha_test(program, message_context)) < 0)
- return result;
+ vsir_transform(&ctx, vsir_program_insert_alpha_test);
if (TRACE_ON())
vkd3d_shader_trace(program);
- if ((result = vsir_program_validate(program, config_flags,
- compile_info->source_name, message_context)) < 0)
- return result;
-
- return result;
+ return ctx.result;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index c1fd07a533a..a3e121f8687 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -10614,7 +10614,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct
enum vkd3d_result result = VKD3D_OK;
unsigned int i, max_element_count;
- if ((result = vsir_program_normalise(program, compiler->config_flags,
+ if ((result = vsir_program_transform(program, compiler->config_flags,
compile_info, compiler->message_context)) < 0)
return result;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index ffec48daa17..bc369ec6866 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -179,6 +179,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT = 7008,
VKD3D_SHADER_ERROR_D3DBC_NOT_IMPLEMENTED = 7009,
VKD3D_SHADER_ERROR_D3DBC_INVALID_PROFILE = 7010,
+ VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK = 7011,
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
@@ -1393,7 +1394,7 @@ const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
const struct vsir_program *program, enum vkd3d_shader_parameter_name name);
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_version *version, unsigned int reserve);
-enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags,
+enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
const char *source_name, struct vkd3d_shader_message_context *message_context);
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index 188162f9e6e..eab0436bebd 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -19,6 +19,7 @@
*/
#include "vkd3d_private.h"
+#include <math.h>
static void d3d12_fence_incref(struct d3d12_fence *fence);
static void d3d12_fence_decref(struct d3d12_fence *fence);
@@ -2451,6 +2452,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL
}
list->is_recording = false;
+ list->has_depth_bounds = false;
if (!list->is_valid)
{
@@ -2479,7 +2481,7 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
list->fb_layer_count = 0;
list->xfb_enabled = false;
-
+ list->has_depth_bounds = false;
list->is_predicated = false;
list->current_framebuffer = VK_NULL_HANDLE;
@@ -3363,6 +3365,12 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list
list->xfb_enabled = true;
}
+ if (graphics->ds_desc.depthBoundsTestEnable && !list->has_depth_bounds)
+ {
+ list->has_depth_bounds = true;
+ VK_CALL(vkCmdSetDepthBounds(list->vk_command_buffer, 0.0f, 1.0f));
+ }
+
return true;
}
@@ -5951,7 +5959,25 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr
static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList6 *iface,
FLOAT min, FLOAT max)
{
- FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max);
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList6(iface);
+ const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
+
+ TRACE("iface %p, min %.8e, max %.8e.\n", iface, min, max);
+
+ if (isnan(max))
+ max = 0.0f;
+ if (isnan(min))
+ min = 0.0f;
+
+ if (!list->device->vk_info.EXT_depth_range_unrestricted && (min < 0.0f || min > 1.0f || max < 0.0f || max > 1.0f))
+ {
+ WARN("VK_EXT_depth_range_unrestricted was not found, clamping depth bounds to 0.0 and 1.0.\n");
+ max = vkd3d_clamp(max, 0.0f, 1.0f);
+ min = vkd3d_clamp(min, 0.0f, 1.0f);
+ }
+
+ list->has_depth_bounds = true;
+ VK_CALL(vkCmdSetDepthBounds(list->vk_command_buffer, min, max));
}
static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList6 *iface,
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 01841c89692..65339c7ba5d 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -102,6 +102,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering),
VK_DEBUG_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker),
+ VK_EXTENSION(EXT_DEPTH_RANGE_UNRESTRICTED, EXT_depth_range_unrestricted),
VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable),
VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing),
VK_EXTENSION(EXT_FRAGMENT_SHADER_INTERLOCK, EXT_fragment_shader_interlock),
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index bc887fa2f33..ea7d8f040b5 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -3867,6 +3867,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+ VK_DYNAMIC_STATE_DEPTH_BOUNDS,
};
static const VkPipelineDynamicStateCreateInfo dynamic_desc =
{
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index 729b1baee18..e6d477a5c12 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -131,6 +131,7 @@ struct vkd3d_vulkan_info
bool EXT_calibrated_timestamps;
bool EXT_conditional_rendering;
bool EXT_debug_marker;
+ bool EXT_depth_range_unrestricted;
bool EXT_depth_clip_enable;
bool EXT_descriptor_indexing;
bool EXT_fragment_shader_interlock;
@@ -1254,7 +1255,7 @@ struct d3d12_command_list
VkFormat dsv_format;
bool xfb_enabled;
-
+ bool has_depth_bounds;
bool is_predicated;
VkFramebuffer current_framebuffer;
--
2.45.2