wine-staging/patches/vkd3d-latest/0007-Updated-vkd3d-to-3e012c355db12ecad32d45a76058c29a407.patch
2024-09-21 09:44:13 +10:00

2282 lines
94 KiB
Diff

From 40af188e9e7e710643821bf227369b58db3a2eb5 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Sun, 15 Sep 2024 07:56:38 +1000
Subject: [PATCH] Updated vkd3d to 3e012c355db12ecad32d45a76058c29a407ac9e4.
---
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 105 +-
libs/vkd3d/libs/vkd3d-shader/fx.c | 3 +
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 85 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 42 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 108 +-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 278 ++----
libs/vkd3d/libs/vkd3d-shader/ir.c | 936 +++++++++---------
.../libs/vkd3d-shader/vkd3d_shader_private.h | 1 +
9 files changed, 723 insertions(+), 836 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index b69b70c6304..9c7be1f08bb 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1474,10 +1474,6 @@ struct d3dbc_compiler
struct vkd3d_bytecode_buffer buffer;
struct vkd3d_shader_message_context *message_context;
bool failed;
-
- /* OBJECTIVE: Store all the required information in the other fields so
- * that this hlsl_ctx is no longer necessary. */
- struct hlsl_ctx *ctx;
};
static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor)
@@ -2162,6 +2158,7 @@ static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc,
return;
instr.opcode = info->sm1_opcode;
+ instr.flags = ins->flags;
instr.has_dst = info->dst_count;
instr.src_count = info->src_count;
@@ -2195,7 +2192,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
case VKD3DSIH_DP4:
case VKD3DSIH_DSX:
case VKD3DSIH_DSY:
+ case VKD3DSIH_ELSE:
+ case VKD3DSIH_ENDIF:
case VKD3DSIH_FRC:
+ case VKD3DSIH_IFC:
case VKD3DSIH_MAD:
case VKD3DSIH_MAX:
case VKD3DSIH_MIN:
@@ -2299,105 +2299,24 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc)
}
}
-static void d3dbc_write_block(struct d3dbc_compiler *d3dbc, const struct hlsl_block *block);
-
-static void d3dbc_write_if(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_node *instr)
-{
- const struct hlsl_ir_if *iff = hlsl_ir_if(instr);
- const struct hlsl_ir_node *condition;
- struct sm1_instruction sm1_ifc, sm1_else, sm1_endif;
-
- condition = iff->condition.node;
- VKD3D_ASSERT(condition->data_type->dimx == 1 && condition->data_type->dimy == 1);
-
- sm1_ifc = (struct sm1_instruction)
- {
- .opcode = VKD3D_SM1_OP_IFC,
- .flags = VKD3D_SHADER_REL_OP_NE, /* Make it a "if_ne" instruction. */
-
- .srcs[0].type = VKD3DSPR_TEMP,
- .srcs[0].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
- .srcs[0].reg = condition->reg.id,
- .srcs[0].mod = 0,
-
- .srcs[1].type = VKD3DSPR_TEMP,
- .srcs[1].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
- .srcs[1].reg = condition->reg.id,
- .srcs[1].mod = VKD3DSPSM_NEG,
-
- .src_count = 2,
- };
- d3dbc_write_instruction(d3dbc, &sm1_ifc);
- d3dbc_write_block(d3dbc, &iff->then_block);
-
- if (!list_empty(&iff->else_block.instrs))
- {
- sm1_else = (struct sm1_instruction){.opcode = VKD3D_SM1_OP_ELSE};
- d3dbc_write_instruction(d3dbc, &sm1_else);
- d3dbc_write_block(d3dbc, &iff->else_block);
- }
-
- sm1_endif = (struct sm1_instruction){.opcode = VKD3D_SM1_OP_ENDIF};
- d3dbc_write_instruction(d3dbc, &sm1_endif);
-}
-
-static void d3dbc_write_block(struct d3dbc_compiler *d3dbc, const struct hlsl_block *block)
+static void d3dbc_write_program_instructions(struct d3dbc_compiler *d3dbc)
{
- struct vkd3d_shader_instruction *vsir_instr;
- struct hlsl_ctx *ctx = d3dbc->ctx;
- const struct hlsl_ir_node *instr;
- unsigned int vsir_instr_idx;
-
- LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
- {
- if (instr->data_type)
- {
- if (instr->data_type->class != HLSL_CLASS_SCALAR && instr->data_type->class != HLSL_CLASS_VECTOR)
- {
- hlsl_fixme(ctx, &instr->loc, "Class %#x should have been lowered or removed.", instr->data_type->class);
- break;
- }
- }
-
- switch (instr->type)
- {
- case HLSL_IR_CALL:
- vkd3d_unreachable();
-
- case HLSL_IR_IF:
- if (hlsl_version_ge(ctx, 2, 1))
- d3dbc_write_if(d3dbc, instr);
- else
- hlsl_fixme(ctx, &instr->loc, "Flatten \"if\" conditionals branches.");
- break;
-
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- vsir_instr_idx = hlsl_ir_vsir_instruction_ref(instr)->vsir_instr_idx;
- vsir_instr = &d3dbc->program->instructions.elements[vsir_instr_idx];
- d3dbc_write_vsir_instruction(d3dbc, vsir_instr);
- break;
+ struct vsir_program *program = d3dbc->program;
+ unsigned int i;
- default:
- hlsl_fixme(ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type));
- }
- }
+ for (i = 0; i < program->instructions.count; ++i)
+ d3dbc_write_vsir_instruction(d3dbc, &program->instructions.elements[i]);
}
-/* OBJECTIVE: Stop relying on ctx and entry_func on this function, receiving
- * data from the other parameters instead, so it can be removed as an argument
- * and be declared in vkd3d_shader_private.h and used without relying on HLSL
- * IR structs. */
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *ctab,
- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context,
- struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
{
const struct vkd3d_shader_version *version = &program->shader_version;
struct d3dbc_compiler d3dbc = {0};
struct vkd3d_bytecode_buffer *buffer = &d3dbc.buffer;
int result;
- d3dbc.ctx = ctx;
d3dbc.program = program;
d3dbc.message_context = message_context;
switch (version->type)
@@ -2421,11 +2340,11 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
bytecode_put_bytes(buffer, ctab->code, ctab->size);
d3dbc_write_semantic_dcls(&d3dbc);
- d3dbc_write_block(&d3dbc, &entry_func->body);
+ d3dbc_write_program_instructions(&d3dbc);
put_u32(buffer, VKD3D_SM1_OP_END);
- result = ctx->result;
+ result = VKD3D_OK;
if (buffer->status)
result = buffer->status;
if (d3dbc.failed)
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index 2c2e486aa0e..1314bc09e73 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -570,6 +570,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
case HLSL_CLASS_VERTEX_SHADER:
return "VertexShader";
+ case HLSL_CLASS_GEOMETRY_SHADER:
+ return "GeometryShader";
+
case HLSL_CLASS_PIXEL_SHADER:
return "PixelShader";
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index 6f737be2e2a..6323260eab7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -969,6 +969,7 @@ static const char * get_case_insensitive_typename(const char *name)
{
"dword",
"float",
+ "geometryshader",
"matrix",
"pixelshader",
"texture",
@@ -1679,22 +1680,6 @@ struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *
return &s->node;
}
-struct hlsl_ir_node *hlsl_new_vsir_instruction_ref(struct hlsl_ctx *ctx, unsigned int vsir_instr_idx,
- struct hlsl_type *type, const struct hlsl_reg *reg, const struct vkd3d_shader_location *loc)
-{
- struct hlsl_ir_vsir_instruction_ref *vsir_instr;
-
- if (!(vsir_instr = hlsl_alloc(ctx, sizeof(*vsir_instr))))
- return NULL;
- init_node(&vsir_instr->node, HLSL_IR_VSIR_INSTRUCTION_REF, type, loc);
- vsir_instr->vsir_instr_idx = vsir_instr_idx;
-
- if (reg)
- vsir_instr->node.reg = *reg;
-
- return &vsir_instr->node;
-}
-
struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
{
@@ -1847,30 +1832,40 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
return &swizzle->node;
}
-struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_name,
- struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs,
- const struct vkd3d_shader_location *loc)
+struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+ const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
+ struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc)
{
const struct hlsl_profile_info *profile_info = NULL;
struct hlsl_ir_compile *compile;
struct hlsl_type *type = NULL;
unsigned int i;
- if (!(profile_info = hlsl_get_target_info(profile_name)))
+ switch (compile_type)
{
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
- return NULL;
- }
+ case HLSL_COMPILE_TYPE_COMPILE:
+ if (!(profile_info = hlsl_get_target_info(profile_name)))
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
+ return NULL;
+ }
- if (profile_info->type == VKD3D_SHADER_TYPE_PIXEL)
- type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
- else if (profile_info->type == VKD3D_SHADER_TYPE_VERTEX)
- type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
+ if (profile_info->type == VKD3D_SHADER_TYPE_PIXEL)
+ type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
+ else if (profile_info->type == VKD3D_SHADER_TYPE_VERTEX)
+ type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
- if (!type)
- {
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile_name);
- return NULL;
+ if (!type)
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile_name);
+ return NULL;
+ }
+
+ break;
+
+ case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+ type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true);
+ break;
}
if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
@@ -1878,6 +1873,7 @@ struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_
init_node(&compile->node, HLSL_IR_COMPILE, type, loc);
+ compile->compile_type = compile_type;
compile->profile = profile_info;
hlsl_block_init(&compile->instrs);
@@ -2271,7 +2267,8 @@ static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx,
if (compile->profile)
profile_name = compile->profile->name;
- if (!(node = hlsl_new_compile(ctx, profile_name, args, compile->args_count, &block, &compile->node.loc)))
+ if (!(node = hlsl_new_compile(ctx, compile->compile_type, profile_name,
+ args, compile->args_count, &block, &compile->node.loc)))
{
hlsl_block_cleanup(&block);
vkd3d_free(args);
@@ -2429,9 +2426,6 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
case HLSL_IR_STATEBLOCK_CONSTANT:
return clone_stateblock_constant(ctx, map, hlsl_ir_stateblock_constant(instr));
-
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- vkd3d_unreachable();
}
vkd3d_unreachable();
@@ -2847,7 +2841,6 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
[HLSL_IR_COMPILE] = "HLSL_IR_COMPILE",
[HLSL_IR_STATEBLOCK_CONSTANT] = "HLSL_IR_STATEBLOCK_CONSTANT",
- [HLSL_IR_VSIR_INSTRUCTION_REF] = "HLSL_IR_VSIR_INSTRUCTION_REF",
};
if (type >= ARRAY_SIZE(names))
@@ -3300,7 +3293,16 @@ static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *bu
{
unsigned int i;
- vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
+ switch (compile->compile_type)
+ {
+ case HLSL_COMPILE_TYPE_COMPILE:
+ vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
+ break;
+
+ case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+ vkd3d_string_buffer_printf(buffer, "ConstructGSWithSO {\n");
+ break;
+ }
dump_block(ctx, buffer, &compile->instrs);
@@ -3420,11 +3422,6 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
case HLSL_IR_STATEBLOCK_CONSTANT:
dump_ir_stateblock_constant(buffer, hlsl_ir_stateblock_constant(instr));
break;
-
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- vkd3d_string_buffer_printf(buffer, "vsir_program instruction %u",
- hlsl_ir_vsir_instruction_ref(instr)->vsir_instr_idx);
- break;
}
}
@@ -3722,10 +3719,6 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
case HLSL_IR_STATEBLOCK_CONSTANT:
free_ir_stateblock_constant(hlsl_ir_stateblock_constant(node));
break;
-
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- vkd3d_free(hlsl_ir_vsir_instruction_ref(node));
- break;
}
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index eece693b48c..20a96692a48 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -326,8 +326,6 @@ enum hlsl_ir_node_type
HLSL_IR_COMPILE,
HLSL_IR_STATEBLOCK_CONSTANT,
-
- HLSL_IR_VSIR_INSTRUCTION_REF,
};
/* Common data for every type of IR instruction node. */
@@ -875,14 +873,22 @@ struct hlsl_ir_compile
{
struct hlsl_ir_node node;
- /* Special field to store the profile argument. */
+ enum hlsl_compile_type
+ {
+ /* A shader compilation through the CompileShader() function or the "compile" syntax. */
+ HLSL_COMPILE_TYPE_COMPILE,
+ /* A call to ConstructGSWithSO(), which receives a geometry shader and retrieves one as well. */
+ HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO,
+ } compile_type;
+
+ /* Special field to store the profile argument for HLSL_COMPILE_TYPE_COMPILE. */
const struct hlsl_profile_info *profile;
/* Block containing the instructions required by the arguments of the
* compilation call. */
struct hlsl_block instrs;
- /* Arguments to the compilation call. For a "compile" or "CompileShader()"
+ /* Arguments to the compilation call. For HLSL_COMPILE_TYPE_COMPILE
* args[0] is an hlsl_ir_call to the specified function. */
struct hlsl_src *args;
unsigned int args_count;
@@ -896,16 +902,6 @@ struct hlsl_ir_stateblock_constant
char *name;
};
-/* A vkd3d_shader_instruction that can be inserted in a hlsl_block.
- * Only used for the HLSL IR to vsir translation, might be removed once this translation is complete. */
-struct hlsl_ir_vsir_instruction_ref
-{
- struct hlsl_ir_node node;
-
- /* Index to a vkd3d_shader_instruction within a vkd3d_shader_instruction_array in a vsir_program. */
- unsigned int vsir_instr_idx;
-};
-
struct hlsl_scope
{
/* Item entry for hlsl_ctx.scopes. */
@@ -1212,12 +1208,6 @@ static inline struct hlsl_ir_stateblock_constant *hlsl_ir_stateblock_constant(co
return CONTAINING_RECORD(node, struct hlsl_ir_stateblock_constant, node);
}
-static inline struct hlsl_ir_vsir_instruction_ref *hlsl_ir_vsir_instruction_ref(const struct hlsl_ir_node *node)
-{
- VKD3D_ASSERT(node->type == HLSL_IR_VSIR_INSTRUCTION_REF);
- return CONTAINING_RECORD(node, struct hlsl_ir_vsir_instruction_ref, node);
-}
-
static inline void hlsl_block_init(struct hlsl_block *block)
{
list_init(&block->instrs);
@@ -1491,9 +1481,9 @@ bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
-struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_name,
- struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs,
- const struct vkd3d_shader_location *loc);
+struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+ const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
+ struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
@@ -1532,9 +1522,6 @@ struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned
struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector,
struct list *cases, const struct vkd3d_shader_location *loc);
-struct hlsl_ir_node *hlsl_new_vsir_instruction_ref(struct hlsl_ctx *ctx, unsigned int vsir_instr_idx,
- struct hlsl_type *type, const struct hlsl_reg *reg, const struct vkd3d_shader_location *loc);
-
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
@@ -1603,8 +1590,7 @@ bool hlsl_sm1_usage_from_semantic(const char *semantic_name,
void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer);
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *ctab,
- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context,
- struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func);
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
bool sysval_semantic_from_hlsl(enum vkd3d_shader_sysval_semantic *semantic,
struct hlsl_ctx *ctx, const struct hlsl_semantic *hlsl_semantic, bool output);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index e5472709a8c..b7c242661e3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -82,6 +82,7 @@ ComputeShader {return KW_COMPUTESHADER; }
compile {return KW_COMPILE; }
CompileShader {return KW_COMPILESHADER; }
const {return KW_CONST; }
+ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; }
continue {return KW_CONTINUE; }
DepthStencilState {return KW_DEPTHSTENCILSTATE; }
DepthStencilView {return KW_DEPTHSTENCILVIEW; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 60e196c63cc..67262c2ccfd 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -609,6 +609,7 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
{
switch (node->type)
{
+ case HLSL_IR_COMPILE:
case HLSL_IR_CONSTANT:
case HLSL_IR_EXPR:
case HLSL_IR_STRING_CONSTANT:
@@ -627,13 +628,10 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
case HLSL_IR_RESOURCE_LOAD:
case HLSL_IR_RESOURCE_STORE:
case HLSL_IR_SWITCH:
- case HLSL_IR_COMPILE:
case HLSL_IR_STATEBLOCK_CONSTANT:
hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
"Expected literal expression.");
break;
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- vkd3d_unreachable();
}
}
@@ -1227,7 +1225,8 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
}
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
- struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src);
+ struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
+ bool is_default_values_initializer);
static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters,
struct parse_parameter *param, const struct vkd3d_shader_location *loc)
@@ -1285,7 +1284,8 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
for (i = 0; i < param->initializer.args_count; ++i)
{
- initialize_var_components(ctx, param->initializer.instrs, var, &store_index, param->initializer.args[i]);
+ initialize_var_components(ctx, param->initializer.instrs, var,
+ &store_index, param->initializer.args[i], true);
}
free_parse_initializer(&param->initializer);
@@ -2368,7 +2368,8 @@ static unsigned int get_component_index_from_default_initializer_index(struct hl
}
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
- struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src)
+ struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
+ bool is_default_values_initializer)
{
unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
struct hlsl_deref dst_deref;
@@ -2387,23 +2388,43 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
- if (dst->default_values)
+ if (is_default_values_initializer)
{
struct hlsl_default_value default_value = {0};
unsigned int dst_index;
- if (!hlsl_clone_block(ctx, &block, instrs))
- return;
- default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
+ if (hlsl_is_numeric_type(dst_comp_type))
+ {
+ if (src->type == HLSL_IR_COMPILE)
+ {
+ /* Default values are discarded if they contain an object
+ * literal expression for a numeric component. */
+ if (dst->default_values)
+ {
+ hlsl_warning(ctx, &src->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE,
+ "Component %u in variable '%s' initializer is object literal. Default values discarded.",
+ k, dst->name);
+ vkd3d_free(dst->default_values);
+ dst->default_values = NULL;
+ }
+ }
+ else
+ {
+ if (!hlsl_clone_block(ctx, &block, instrs))
+ return;
+ default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
- if (dst->is_param)
- dst_index = *store_index;
- else
- dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
+ if (dst->is_param)
+ dst_index = *store_index;
+ else
+ dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
- dst->default_values[dst_index] = default_value;
+ if (dst->default_values)
+ dst->default_values[dst_index] = default_value;
- hlsl_block_cleanup(&block);
+ hlsl_block_cleanup(&block);
+ }
+ }
}
else
{
@@ -2793,7 +2814,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
for (k = 0; k < v->initializer.args_count; ++k)
{
- initialize_var_components(ctx, v->initializer.instrs, var, &store_index, v->initializer.args[k]);
+ initialize_var_components(ctx, v->initializer.instrs, var,
+ &store_index, v->initializer.args[k], is_default_values_initializer);
}
if (is_default_values_initializer)
@@ -4785,17 +4807,17 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc)))
return false;
- initialize_var_components(ctx, params->instrs, var, &idx, coords);
+ initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
if (hlsl_version_ge(ctx, 4, 0))
{
if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc)))
return false;
hlsl_block_add_instr(params->instrs, half);
- initialize_var_components(ctx, params->instrs, var, &idx, half);
+ initialize_var_components(ctx, params->instrs, var, &idx, half, false);
}
else
- initialize_var_components(ctx, params->instrs, var, &idx, coords);
+ initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
if (!(load = hlsl_new_var_load(ctx, var, loc)))
return false;
@@ -5224,7 +5246,38 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
return NULL;
}
- if (!(compile = hlsl_new_compile(ctx, profile_name, &call_to_compile, 1, args->instrs, loc)))
+ if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_COMPILE,
+ profile_name, &call_to_compile, 1, args->instrs, loc)))
+ {
+ free_parse_initializer(args);
+ return NULL;
+ }
+
+ free_parse_initializer(args);
+ return make_block(ctx, compile);
+}
+
+static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+ struct parse_initializer *args, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_node *compile;
+
+ switch (compile_type)
+ {
+ case HLSL_COMPILE_TYPE_COMPILE:
+ vkd3d_unreachable();
+
+ case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+ if (args->args_count != 2 && args->args_count != 6)
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.",
+ args->args_count);
+ }
+ break;
+ }
+
+ if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc)))
{
free_parse_initializer(args);
return NULL;
@@ -5245,7 +5298,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type
return NULL;
for (i = 0; i < params->args_count; ++i)
- initialize_var_components(ctx, params->instrs, var, &idx, params->args[i]);
+ initialize_var_components(ctx, params->instrs, var, &idx, params->args[i], false);
if (!(load = hlsl_new_var_load(ctx, var, loc)))
return NULL;
@@ -6235,6 +6288,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%token KW_COMPILESHADER
%token KW_COMPUTESHADER
%token KW_CONST
+%token KW_CONSTRUCTGSWITHSO
%token KW_CONTINUE
%token KW_DEFAULT
%token KW_DEPTHSTENCILSTATE
@@ -7796,6 +7850,11 @@ stateblock_lhs_identifier:
if (!($$ = hlsl_strdup(ctx, "vertexshader")))
YYABORT;
}
+ | KW_GEOMETRYSHADER
+ {
+ if (!($$ = hlsl_strdup(ctx, "geometryshader")))
+ YYABORT;
+ }
state_block_index_opt:
%empty
@@ -8590,6 +8649,11 @@ primary_expr:
vkd3d_free($3);
vkd3d_free($5);
}
+ | KW_CONSTRUCTGSWITHSO '(' func_arguments ')'
+ {
+ if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1)))
+ YYABORT;
+ }
| var_identifier '(' func_arguments ')'
{
if (!($$ = add_call(ctx, $1, &$3, &@1)))
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 93f19360953..6cae0e3b5c9 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -4089,9 +4089,6 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
case HLSL_IR_STATEBLOCK_CONSTANT:
/* Stateblock constants should not appear in the shader program. */
vkd3d_unreachable();
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- /* HLSL IR nodes are not translated to hlsl_ir_vsir_instruction_ref at this point. */
- vkd3d_unreachable();
}
return false;
@@ -4217,9 +4214,6 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
case HLSL_IR_STATEBLOCK_CONSTANT:
/* Stateblock constants should not appear in the shader program. */
vkd3d_unreachable();
- case HLSL_IR_VSIR_INSTRUCTION_REF:
- /* HLSL IR nodes are not translated to hlsl_ir_vsir_instruction_ref at this point. */
- vkd3d_unreachable();
case HLSL_IR_STORE:
{
@@ -6312,7 +6306,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr
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, x;
for (i = 0; i < ctx->constant_defs.count; ++i)
@@ -6349,14 +6342,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr
for (x = 0; x < 4; ++x)
src_param->reg.u.immconst_f32[x] = constant_reg->value.f[x];
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
-
- if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, NULL, NULL,
- &constant_reg->loc)))
- {
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return;
- }
- hlsl_block_add_instr(block, vsir_instr);
}
}
@@ -6370,7 +6355,6 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx,
struct vkd3d_shader_semantic *semantic;
struct vkd3d_shader_instruction *ins;
enum hlsl_sampler_dim sampler_dim;
- struct hlsl_ir_node *vsir_instr;
struct hlsl_ir_var *var;
unsigned int i, count;
@@ -6435,14 +6419,6 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx,
range = &semantic->resource.range;
range->space = 0;
range->first = range->last = dst_param->reg.idx[0].offset;
-
- if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, NULL,
- NULL, &var->loc)))
- {
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return;
- }
- hlsl_block_add_instr(block, vsir_instr);
}
}
}
@@ -6474,12 +6450,10 @@ static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(
static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_ir_constant *constant)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *instr = &constant->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;
VKD3D_ASSERT(instr->reg.allocated);
VKD3D_ASSERT(constant->reg.allocated);
@@ -6496,16 +6470,6 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
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;
-
- 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 can be mapped to a single vsir instruction with only one dst register. */
@@ -6513,12 +6477,10 @@ static void sm1_generate_vsir_instr_expr_single_instr_op(struct hlsl_ctx *ctx, s
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);
@@ -6550,16 +6512,6 @@ static void sm1_generate_vsir_instr_expr_single_instr_op(struct hlsl_ctx *ctx, s
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
@@ -6567,12 +6519,10 @@ static void sm1_generate_vsir_instr_expr_single_instr_op(struct hlsl_ctx *ctx, s
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;
@@ -6598,52 +6548,18 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx
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);
@@ -6674,16 +6590,6 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi
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_cast(struct hlsl_ctx *ctx,
@@ -6898,6 +6804,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
break;
default:
+ hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op));
return false;
}
@@ -7018,11 +6925,9 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx,
static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_program *program,
struct hlsl_ir_load *load)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *instr = &load->node;
struct vkd3d_shader_dst_param *dst_param;
struct vkd3d_shader_instruction *ins;
- struct hlsl_ir_node *vsir_instr;
VKD3D_ASSERT(instr->reg.allocated);
@@ -7036,22 +6941,11 @@ static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr
sm1_generate_vsir_init_src_param_from_deref(ctx, &ins->src[0], &load->src, dst_param->write_mask,
&ins->location);
-
- 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_resource_load(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_ir_resource_load *load)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *coords = load->coords.node;
struct hlsl_ir_node *ddx = load->ddx.node;
struct hlsl_ir_node *ddy = load->ddy.node;
@@ -7059,7 +6953,6 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
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;
enum vkd3d_shader_opcode opcode;
unsigned int src_count = 2;
uint32_t flags = 0;
@@ -7121,27 +7014,15 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
src_param->reg.idx[0].offset = ddy->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(ddy->reg.writemask, VKD3DSP_WRITEMASK_ALL);
}
-
- 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_swizzle(struct hlsl_ctx *ctx, struct vsir_program *program,
struct hlsl_ir_swizzle *swizzle_instr)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *instr = &swizzle_instr->node, *val = swizzle_instr->val.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;
uint32_t swizzle;
VKD3D_ASSERT(instr->reg.allocated);
@@ -7163,27 +7044,15 @@ static void sm1_generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, struct vsir_pr
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
src_param->reg.idx[0].offset = val->reg.id;
src_param->swizzle = 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 void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_program *program,
struct hlsl_ir_store *store)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *rhs = store->rhs.node;
struct hlsl_ir_node *instr = &store->node;
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_src_param *src_param;
- struct hlsl_ir_node *vsir_instr;
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
return;
@@ -7194,26 +7063,15 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
src_param->reg.idx[0].offset = rhs->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(rhs->reg.writemask, ins->dst[0].write_mask);
-
- if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, instructions->count - 1, NULL, NULL, &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_jump(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_ir_jump *jump)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct hlsl_ir_node *condition = jump->condition.node;
struct hlsl_ir_node *instr = &jump->node;
struct vkd3d_shader_dst_param *dst_param;
struct vkd3d_shader_instruction *ins;
- struct hlsl_ir_node *vsir_instr;
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG)
{
@@ -7224,16 +7082,6 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
dst_param->reg.idx[0].offset = condition->reg.id;
dst_param->write_mask = condition->reg.writemask;
-
- if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx,
- instructions->count - 1, instr->data_type, NULL, &instr->loc)))
- {
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return;
- }
-
- list_add_before(&instr->entry, &vsir_instr->entry);
- hlsl_replace_node(instr, vsir_instr);
}
else
{
@@ -7241,44 +7089,110 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
}
}
-static bool sm1_generate_vsir_instr(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program);
+
+static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_if *iff)
{
- struct vsir_program *program = context;
+ struct hlsl_ir_node *condition = iff->condition.node;
+ struct vkd3d_shader_src_param *src_param;
+ struct hlsl_ir_node *instr = &iff->node;
+ struct vkd3d_shader_instruction *ins;
+ uint32_t swizzle;
- switch (instr->type)
+ if (hlsl_version_lt(ctx, 2, 1))
{
- case HLSL_IR_CONSTANT:
- sm1_generate_vsir_instr_constant(ctx, program, hlsl_ir_constant(instr));
- return true;
+ hlsl_fixme(ctx, &instr->loc, "Flatten \"if\" conditionals branches.");
+ return;
+ }
+ VKD3D_ASSERT(condition->data_type->dimx == 1 && condition->data_type->dimy == 1);
- case HLSL_IR_EXPR:
- return sm1_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr));
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IFC, 0, 2)))
+ return;
+ ins->flags = VKD3D_SHADER_REL_OP_NE;
- case HLSL_IR_JUMP:
- sm1_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr));
- return true;
+ swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask);
+ swizzle = vsir_swizzle_from_hlsl(swizzle);
- case HLSL_IR_LOAD:
- sm1_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr));
- return true;
+ src_param = &ins->src[0];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = condition->reg.id;
+ src_param->swizzle = swizzle;
+ src_param->modifiers = 0;
- case HLSL_IR_RESOURCE_LOAD:
- sm1_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr));
- return true;
+ src_param = &ins->src[1];
+ vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src_param->reg.idx[0].offset = condition->reg.id;
+ src_param->swizzle = swizzle;
+ src_param->modifiers = VKD3DSPSM_NEG;
- case HLSL_IR_STORE:
- sm1_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr));
- return true;
+ sm1_generate_vsir_block(ctx, &iff->then_block, program);
- case HLSL_IR_SWIZZLE:
- sm1_generate_vsir_instr_swizzle(ctx, program, hlsl_ir_swizzle(instr));
- return true;
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0)))
+ return;
- default:
- break;
- }
+ sm1_generate_vsir_block(ctx, &iff->else_block, program);
- return false;
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0)))
+ return;
+}
+
+static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program)
+{
+ struct hlsl_ir_node *instr, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry)
+ {
+ if (instr->data_type)
+ {
+ if (instr->data_type->class != HLSL_CLASS_SCALAR && instr->data_type->class != HLSL_CLASS_VECTOR)
+ {
+ hlsl_fixme(ctx, &instr->loc, "Class %#x should have been lowered or removed.", instr->data_type->class);
+ break;
+ }
+ }
+
+ switch (instr->type)
+ {
+ case HLSL_IR_CALL:
+ vkd3d_unreachable();
+
+ case HLSL_IR_CONSTANT:
+ sm1_generate_vsir_instr_constant(ctx, program, hlsl_ir_constant(instr));
+ break;
+
+ case HLSL_IR_EXPR:
+ sm1_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr));
+ break;
+
+ case HLSL_IR_IF:
+ sm1_generate_vsir_instr_if(ctx, program, hlsl_ir_if(instr));
+ break;
+
+ case HLSL_IR_JUMP:
+ sm1_generate_vsir_instr_jump(ctx, program, hlsl_ir_jump(instr));
+ break;
+
+ case HLSL_IR_LOAD:
+ sm1_generate_vsir_instr_load(ctx, program, hlsl_ir_load(instr));
+ break;
+
+ case HLSL_IR_RESOURCE_LOAD:
+ sm1_generate_vsir_instr_resource_load(ctx, program, hlsl_ir_resource_load(instr));
+ break;
+
+ case HLSL_IR_STORE:
+ sm1_generate_vsir_instr_store(ctx, program, hlsl_ir_store(instr));
+ break;
+
+ case HLSL_IR_SWIZZLE:
+ sm1_generate_vsir_instr_swizzle(ctx, program, hlsl_ir_swizzle(instr));
+ break;
+
+ default:
+ hlsl_fixme(ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type));
+ break;
+ }
+ }
}
/* OBJECTIVE: Translate all the information from ctx and entry_func to the
@@ -7317,7 +7231,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
sm1_generate_vsir_sampler_dcls(ctx, program, &block);
list_move_head(&entry_func->body.instrs, &block.instrs);
- hlsl_transform_ir(ctx, sm1_generate_vsir_instr, &entry_func->body, program);
+ sm1_generate_vsir_block(ctx, &entry_func->body, program);
}
static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point,
@@ -7818,7 +7732,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
return ctx->result;
}
- result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context, ctx, entry_func);
+ result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context);
vsir_program_cleanup(&program);
vkd3d_shader_free_shader_code(&ctab);
return result;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 4b79a058b6f..1efb7106e71 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -127,23 +127,134 @@ const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
return NULL;
}
+void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_data_type data_type, unsigned int idx_count)
+{
+ reg->type = reg_type;
+ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
+ reg->non_uniform = false;
+ reg->data_type = data_type;
+ reg->idx[0].offset = ~0u;
+ reg->idx[0].rel_addr = NULL;
+ reg->idx[0].is_in_bounds = false;
+ reg->idx[1].offset = ~0u;
+ reg->idx[1].rel_addr = NULL;
+ reg->idx[1].is_in_bounds = false;
+ reg->idx[2].offset = ~0u;
+ reg->idx[2].rel_addr = NULL;
+ reg->idx[2].is_in_bounds = false;
+ reg->idx_count = idx_count;
+ reg->dimension = VSIR_DIMENSION_SCALAR;
+ reg->alignment = 0;
+}
+
static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID;
}
-static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
+void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_data_type data_type, unsigned int idx_count)
{
- enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_DCL <= opcode && opcode <= VKD3DSIH_DCL_VERTICES_OUT)
- || opcode == VKD3DSIH_HS_DECLS;
+ vsir_register_init(&param->reg, reg_type, data_type, idx_count);
+ param->swizzle = 0;
+ param->modifiers = VKD3DSPSM_NONE;
}
-static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
+static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value)
{
- struct vkd3d_shader_location location = ins->location;
+ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
+ src->reg.u.immconst_u32[0] = value;
+}
- vsir_instruction_init(ins, &location, VKD3DSIH_NOP);
+void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
+{
+ vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
+ param->reg.dimension = VSIR_DIMENSION_NONE;
+ param->reg.idx[0].offset = label_id;
+}
+
+static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
+{
+ vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_RESOURCE, 2);
+ src->reg.idx[0].offset = id;
+ src->reg.idx[1].offset = idx;
+ src->reg.dimension = VSIR_DIMENSION_VEC4;
+ src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+}
+
+static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_SAMPLER, VKD3D_DATA_SAMPLER, 2);
+ src->reg.idx[0].offset = id;
+ src->reg.idx[1].offset = idx;
+ src->reg.dimension = VSIR_DIMENSION_NONE;
+}
+
+static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_data_type data_type, unsigned int idx_count)
+{
+ vsir_register_init(&param->reg, reg_type, data_type, idx_count);
+ param->write_mask = VKD3DSP_WRITEMASK_0;
+ param->modifiers = VKD3DSPDM_NONE;
+ param->shift = 0;
+}
+
+static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ dst->reg.idx[0].offset = idx;
+}
+
+static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ dst->reg.idx[0].offset = idx;
+}
+
+static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ dst->reg.idx[0].offset = idx;
+ dst->write_mask = VKD3DSP_WRITEMASK_0;
+}
+
+void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
+ enum vkd3d_shader_opcode opcode)
+{
+ memset(ins, 0, sizeof(*ins));
+ ins->location = *location;
+ ins->opcode = opcode;
}
bool vsir_instruction_init_with_params(struct vsir_program *program,
@@ -171,6 +282,37 @@ bool vsir_instruction_init_with_params(struct vsir_program *program,
return true;
}
+static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
+ const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program)
+{
+ struct vkd3d_shader_src_param *src_param;
+
+ if (!(src_param = vsir_program_get_src_params(program, 1)))
+ return false;
+
+ vsir_src_param_init_label(src_param, label_id);
+
+ vsir_instruction_init(ins, location, VKD3DSIH_LABEL);
+ ins->src = src_param;
+ ins->src_count = 1;
+
+ return true;
+}
+
+static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
+{
+ enum vkd3d_shader_opcode opcode = instruction->opcode;
+ return (VKD3DSIH_DCL <= opcode && opcode <= VKD3DSIH_DCL_VERTICES_OUT)
+ || opcode == VKD3DSIH_HS_DECLS;
+}
+
+static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
+{
+ struct vkd3d_shader_location location = ins->location;
+
+ vsir_instruction_init(ins, &location, VKD3DSIH_NOP);
+}
+
static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type,
enum vkd3d_shader_opcode *opcode, bool *requires_swap)
{
@@ -451,6 +593,53 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog
return VKD3D_OK;
}
+static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *tex)
+{
+ unsigned int idx = tex->src[1].reg.idx[0].offset;
+ struct vkd3d_shader_src_param *srcs;
+
+ VKD3D_ASSERT(tex->src[1].reg.idx_count == 1);
+ VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr);
+
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ srcs[0] = tex->src[0];
+ vsir_src_param_init_resource(&srcs[1], idx, idx);
+ vsir_src_param_init_sampler(&srcs[2], idx, idx);
+
+ tex->opcode = VKD3DSIH_SAMPLE;
+ tex->src = srcs;
+ tex->src_count = 3;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program,
+ struct vkd3d_shader_instruction *texldd)
+{
+ unsigned int idx = texldd->src[1].reg.idx[0].offset;
+ struct vkd3d_shader_src_param *srcs;
+
+ VKD3D_ASSERT(texldd->src[1].reg.idx_count == 1);
+ VKD3D_ASSERT(!texldd->src[1].reg.idx[0].rel_addr);
+
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 5)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ srcs[0] = texldd->src[0];
+ vsir_src_param_init_resource(&srcs[1], idx, idx);
+ vsir_src_param_init_sampler(&srcs[2], idx, idx);
+ srcs[3] = texldd->src[2];
+ srcs[4] = texldd->src[3];
+
+ texldd->opcode = VKD3DSIH_SAMPLE_GRAD;
+ texldd->src = srcs;
+ texldd->src_count = 5;
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
@@ -492,6 +681,38 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
return ret;
break;
+ case VKD3DSIH_TEX:
+ if ((ret = vsir_program_lower_tex(program, ins)) < 0)
+ return ret;
+ break;
+
+ case VKD3DSIH_TEXLDD:
+ if ((ret = vsir_program_lower_texldd(program, ins)) < 0)
+ return ret;
+ break;
+
+ case VKD3DSIH_TEXBEM:
+ case VKD3DSIH_TEXBEML:
+ case VKD3DSIH_TEXCOORD:
+ case VKD3DSIH_TEXDEPTH:
+ case VKD3DSIH_TEXDP3:
+ case VKD3DSIH_TEXDP3TEX:
+ case VKD3DSIH_TEXLDL:
+ case VKD3DSIH_TEXM3x2PAD:
+ case VKD3DSIH_TEXM3x2TEX:
+ case VKD3DSIH_TEXM3x3DIFF:
+ case VKD3DSIH_TEXM3x3PAD:
+ case VKD3DSIH_TEXM3x3SPEC:
+ case VKD3DSIH_TEXM3x3TEX:
+ case VKD3DSIH_TEXM3x3VSPEC:
+ case VKD3DSIH_TEXREG2AR:
+ case VKD3DSIH_TEXREG2GB:
+ case VKD3DSIH_TEXREG2RGB:
+ vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to unimplemented feature: Combined sampler instruction %#x.",
+ ins->opcode);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+
default:
break;
}
@@ -689,180 +910,55 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
loc->instruction_count = index - normaliser->phase_body_idx;
}
}
-
-static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser,
- struct shader_phase_location_array *locations)
-{
- struct shader_phase_location *loc;
- unsigned int i, j, k, end, count;
-
- for (i = 0, count = 0; i < locations->count; ++i)
- count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count;
-
- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- end = normaliser->instructions.count;
- normaliser->instructions.count += count;
-
- for (i = locations->count; i > 0; --i)
- {
- loc = &locations->locations[i - 1];
- j = loc->index + loc->instruction_count;
- memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j],
- (end - j) * sizeof(*normaliser->instructions.elements));
- end = j;
- count -= (loc->instance_count - 1) * loc->instruction_count;
- loc->index += count;
- }
-
- for (i = 0, count = 0; i < locations->count; ++i)
- {
- loc = &locations->locations[i];
- /* Make a copy of the non-dcl instructions for each instance. */
- for (j = 1; j < loc->instance_count; ++j)
- {
- for (k = 0; k < loc->instruction_count; ++k)
- {
- if (!shader_instruction_array_clone_instruction(&normaliser->instructions,
- loc->index + loc->instruction_count * j + k, loc->index + k))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- }
- }
- /* Replace each reference to the instance id with a constant instance id. */
- for (j = 0; j < loc->instance_count; ++j)
- {
- for (k = 0; k < loc->instruction_count; ++k)
- shader_instruction_eliminate_phase_instance_id(
- &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j);
- }
- }
-
- return VKD3D_OK;
-}
-
-void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
-{
- reg->type = reg_type;
- reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
- reg->non_uniform = false;
- reg->data_type = data_type;
- reg->idx[0].offset = ~0u;
- reg->idx[0].rel_addr = NULL;
- reg->idx[0].is_in_bounds = false;
- reg->idx[1].offset = ~0u;
- reg->idx[1].rel_addr = NULL;
- reg->idx[1].is_in_bounds = false;
- reg->idx[2].offset = ~0u;
- reg->idx[2].rel_addr = NULL;
- reg->idx[2].is_in_bounds = false;
- reg->idx_count = idx_count;
- reg->dimension = VSIR_DIMENSION_SCALAR;
- reg->alignment = 0;
-}
-
-void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
-{
- vsir_register_init(&param->reg, reg_type, data_type, idx_count);
- param->swizzle = 0;
- param->modifiers = VKD3DSPSM_NONE;
-}
-
-void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
-{
- vsir_register_init(&param->reg, reg_type, data_type, idx_count);
- param->write_mask = VKD3DSP_WRITEMASK_0;
- param->modifiers = VKD3DSPDM_NONE;
- param->shift = 0;
-}
-
-void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
-{
- vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
- param->reg.dimension = VSIR_DIMENSION_NONE;
- param->reg.idx[0].offset = label_id;
-}
-
-static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
-{
- vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
- src->reg.idx[0].offset = idx;
-}
-
-static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
-{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
- src->reg.idx[0].offset = idx;
-}
-
-static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
-{
- vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
- dst->reg.idx[0].offset = idx;
-}
-
-static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
-{
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
- dst->reg.idx[0].offset = idx;
-}
-
-static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx)
-{
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
- dst->reg.idx[0].offset = idx;
- dst->write_mask = VKD3DSP_WRITEMASK_0;
-}
-
-static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx)
-{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
- src->reg.idx[0].offset = idx;
-}
-
-static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx)
-{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
- src->reg.idx[0].offset = idx;
-}
-
-static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value)
-{
- vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
- src->reg.u.immconst_u32[0] = value;
-}
-
-static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
-{
- vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
- src->reg.idx[0].offset = idx;
-}
-
-void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
- enum vkd3d_shader_opcode opcode)
-{
- memset(ins, 0, sizeof(*ins));
- ins->location = *location;
- ins->opcode = opcode;
-}
-
-static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
- const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program)
+
+static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser,
+ struct shader_phase_location_array *locations)
{
- struct vkd3d_shader_src_param *src_param;
+ struct shader_phase_location *loc;
+ unsigned int i, j, k, end, count;
- if (!(src_param = vsir_program_get_src_params(program, 1)))
- return false;
+ for (i = 0, count = 0; i < locations->count; ++i)
+ count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count;
- vsir_src_param_init_label(src_param, label_id);
+ if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ end = normaliser->instructions.count;
+ normaliser->instructions.count += count;
- vsir_instruction_init(ins, location, VKD3DSIH_LABEL);
- ins->src = src_param;
- ins->src_count = 1;
+ for (i = locations->count; i > 0; --i)
+ {
+ loc = &locations->locations[i - 1];
+ j = loc->index + loc->instruction_count;
+ memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j],
+ (end - j) * sizeof(*normaliser->instructions.elements));
+ end = j;
+ count -= (loc->instance_count - 1) * loc->instruction_count;
+ loc->index += count;
+ }
- return true;
+ for (i = 0, count = 0; i < locations->count; ++i)
+ {
+ loc = &locations->locations[i];
+ /* Make a copy of the non-dcl instructions for each instance. */
+ for (j = 1; j < loc->instance_count; ++j)
+ {
+ for (k = 0; k < loc->instruction_count; ++k)
+ {
+ if (!shader_instruction_array_clone_instruction(&normaliser->instructions,
+ loc->index + loc->instruction_count * j + k, loc->index + k))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ /* Replace each reference to the instance id with a constant instance id. */
+ for (j = 0; j < loc->instance_count; ++j)
+ {
+ for (k = 0; k < loc->instruction_count; ++k)
+ shader_instruction_eliminate_phase_instance_id(
+ &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j);
+ }
+ }
+
+ return VKD3D_OK;
}
static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program,
@@ -2055,106 +2151,6 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_normalise_combined_samplers(struct vsir_program *program,
- struct vsir_transformation_context *ctx)
-{
- unsigned int i;
-
- for (i = 0; i < program->instructions.count; ++i)
- {
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
- struct vkd3d_shader_src_param *srcs;
-
- switch (ins->opcode)
- {
- case VKD3DSIH_TEX:
- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- memset(srcs, 0, sizeof(*srcs) * 3);
-
- ins->opcode = VKD3DSIH_SAMPLE;
-
- srcs[0] = ins->src[0];
-
- srcs[1].reg.type = VKD3DSPR_RESOURCE;
- srcs[1].reg.idx[0] = ins->src[1].reg.idx[0];
- srcs[1].reg.idx[1] = ins->src[1].reg.idx[0];
- srcs[1].reg.idx_count = 2;
- srcs[1].reg.data_type = VKD3D_DATA_RESOURCE;
- srcs[1].reg.dimension = VSIR_DIMENSION_VEC4;
- srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
-
- srcs[2].reg.type = VKD3DSPR_SAMPLER;
- srcs[2].reg.idx[0] = ins->src[1].reg.idx[0];
- srcs[2].reg.idx[1] = ins->src[1].reg.idx[0];
- srcs[2].reg.idx_count = 2;
- srcs[2].reg.data_type = VKD3D_DATA_SAMPLER;
-
- ins->src = srcs;
- ins->src_count = 3;
- break;
-
- case VKD3DSIH_TEXLDD:
- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 5)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- memset(srcs, 0, sizeof(*srcs) * 5);
-
- ins->opcode = VKD3DSIH_SAMPLE_GRAD;
-
- srcs[0] = ins->src[0];
-
- srcs[1].reg.type = VKD3DSPR_RESOURCE;
- srcs[1].reg.idx[0] = ins->src[1].reg.idx[0];
- srcs[1].reg.idx[1] = ins->src[1].reg.idx[0];
- srcs[1].reg.idx_count = 2;
- srcs[1].reg.data_type = VKD3D_DATA_RESOURCE;
- srcs[1].reg.dimension = VSIR_DIMENSION_VEC4;
- srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
-
- srcs[2].reg.type = VKD3DSPR_SAMPLER;
- srcs[2].reg.idx[0] = ins->src[1].reg.idx[0];
- srcs[2].reg.idx[1] = ins->src[1].reg.idx[0];
- srcs[2].reg.idx_count = 2;
- srcs[2].reg.data_type = VKD3D_DATA_SAMPLER;
-
- srcs[3] = ins->src[2];
- srcs[4] = ins->src[3];
-
- ins->src = srcs;
- ins->src_count = 5;
- break;
-
- case VKD3DSIH_TEXBEM:
- case VKD3DSIH_TEXBEML:
- case VKD3DSIH_TEXCOORD:
- case VKD3DSIH_TEXDEPTH:
- case VKD3DSIH_TEXDP3:
- case VKD3DSIH_TEXDP3TEX:
- case VKD3DSIH_TEXLDL:
- case VKD3DSIH_TEXM3x2PAD:
- case VKD3DSIH_TEXM3x2TEX:
- case VKD3DSIH_TEXM3x3DIFF:
- case VKD3DSIH_TEXM3x3PAD:
- case VKD3DSIH_TEXM3x3SPEC:
- case VKD3DSIH_TEXM3x3TEX:
- case VKD3DSIH_TEXM3x3VSPEC:
- case VKD3DSIH_TEXREG2AR:
- case VKD3DSIH_TEXREG2GB:
- case VKD3DSIH_TEXREG2RGB:
- 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;
-
- default:
- break;
- }
- }
-
- return VKD3D_OK;
-}
-
struct cf_flattener_if_info
{
struct vkd3d_shader_src_param *false_param;
@@ -6157,6 +6153,48 @@ static void vsir_validator_push_block(struct validation_context *ctx, enum vkd3d
ctx->blocks[ctx->depth++] = opcode;
}
+static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ size_t i;
+
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
+ vsir_validate_dst_count(ctx, instruction, 0);
+
+ if (!vsir_validate_src_min_count(ctx, instruction, 1))
+ return;
+
+ if (vsir_register_is_label(&instruction->src[0].reg))
+ {
+ /* Unconditional branch: parameters are jump label,
+ * optional merge label, optional continue label. */
+ vsir_validate_src_max_count(ctx, instruction, 3);
+
+ for (i = 0; i < instruction->src_count; ++i)
+ {
+ if (!vsir_register_is_label(&instruction->src[i].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid register of type %#x in unconditional BRANCH instruction, expected LABEL.",
+ instruction->src[i].reg.type);
+ }
+ }
+ else
+ {
+ /* Conditional branch: parameters are condition, true
+ * jump label, false jump label, optional merge label,
+ * optional continue label. */
+ vsir_validate_src_min_count(ctx, instruction, 3);
+ vsir_validate_src_max_count(ctx, instruction, 5);
+
+ for (i = 1; i < instruction->src_count; ++i)
+ {
+ if (!vsir_register_is_label(&instruction->src[i].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid register of type %#x in conditional BRANCH instruction, expected LABEL.",
+ instruction->src[i].reg.type);
+ }
+ }
+}
+
static void vsir_validate_dcl_temps(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction)
{
@@ -6211,6 +6249,16 @@ static void vsir_validate_endrep(struct validation_context *ctx, const struct vk
--ctx->depth;
}
+static void vsir_validate_endswitch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
+ "ENDSWITCH instruction doesn't terminate SWITCH block.");
+ else
+ --ctx->depth;
+}
+
static void vsir_validate_if(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
@@ -6223,6 +6271,15 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d
vsir_validator_push_block(ctx, VKD3DSIH_IF);
}
+static void vsir_validate_label(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
+ if (instruction->src_count >= 1 && !vsir_register_is_label(&instruction->src[0].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid register of type %#x in a LABEL instruction, expected LABEL.",
+ instruction->src[0].reg.type);
+}
+
static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
@@ -6230,12 +6287,133 @@ static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3
vsir_validator_push_block(ctx, VKD3DSIH_LOOP);
}
+static void vsir_validate_nop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+}
+
+static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ unsigned int i, incoming_count;
+
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
+
+ vsir_validate_src_min_count(ctx, instruction, 2);
+
+ if (instruction->src_count % 2 != 0)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
+ "Invalid source count %u for a PHI instruction, it must be an even number.",
+ instruction->src_count);
+ incoming_count = instruction->src_count / 2;
+
+ for (i = 0; i < incoming_count; ++i)
+ {
+ unsigned int value_idx = 2 * i;
+ unsigned int label_idx = 2 * i + 1;
+
+ if (!register_is_constant_or_undef(&instruction->src[value_idx].reg)
+ && !register_is_ssa(&instruction->src[value_idx].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid value register for incoming %u of type %#x in PHI instruction, "
+ "expected SSA, IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
+
+ if (instruction->src[value_idx].reg.dimension != VSIR_DIMENSION_SCALAR)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
+ "Invalid value dimension %#x for incoming %u in PHI instruction, expected scalar.",
+ instruction->src[value_idx].reg.dimension, i);
+
+ if (!vsir_register_is_label(&instruction->src[label_idx].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid label register for case %u of type %#x in PHI instruction, "
+ "expected LABEL.", i, instruction->src[value_idx].reg.type);
+ }
+
+ if (instruction->dst_count < 1)
+ return;
+
+ if (!register_is_ssa(&instruction->dst[0].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid destination of type %#x in PHI instruction, expected SSA.",
+ instruction->dst[0].reg.type);
+
+ if (instruction->dst[0].reg.dimension != VSIR_DIMENSION_SCALAR)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
+ "Invalid destination dimension %#x in PHI instruction, expected scalar.",
+ instruction->dst[0].reg.dimension);
+
+ if (instruction->dst[0].modifiers != VKD3DSPDM_NONE)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS,
+ "Invalid modifiers %#x for the destination of a PHI instruction, expected none.",
+ instruction->dst[0].modifiers);
+
+ if (instruction->dst[0].shift != 0)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT,
+ "Invalid shift %#x for the destination of a PHI instruction, expected none.",
+ instruction->dst[0].shift);
+}
+
static void vsir_validate_rep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
vsir_validator_push_block(ctx, VKD3DSIH_REP);
}
+static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+}
+
+static void vsir_validate_switch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
+ vsir_validator_push_block(ctx, VKD3DSIH_SWITCH);
+}
+
+static void vsir_validate_switch_monolithic(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ unsigned int i, case_count;
+
+ vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
+
+ /* Parameters are source, default label, merge label and
+ * then pairs of constant value and case label. */
+
+ if (!vsir_validate_src_min_count(ctx, instruction, 3))
+ return;
+
+ if (instruction->src_count % 2 != 1)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
+ "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.",
+ instruction->src_count);
+
+ if (!vsir_register_is_label(&instruction->src[1].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid default label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
+ instruction->src[1].reg.type);
+
+ if (!vsir_register_is_label(&instruction->src[2].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid merge label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
+ instruction->src[2].reg.type);
+
+ case_count = (instruction->src_count - 3) / 2;
+
+ for (i = 0; i < case_count; ++i)
+ {
+ unsigned int value_idx = 3 + 2 * i;
+ unsigned int label_idx = 3 + 2 * i + 1;
+
+ if (!register_is_constant(&instruction->src[value_idx].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid value register for case %u of type %#x in monolithic SWITCH instruction, "
+ "expected IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
+
+ if (!vsir_register_is_label(&instruction->src[label_idx].reg))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
+ "Invalid label register for case %u of type %#x in monolithic SWITCH instruction, "
+ "expected LABEL.", i, instruction->src[value_idx].reg.type);
+ }
+}
+
struct vsir_validator_instruction_desc
{
unsigned int dst_param_count;
@@ -6245,15 +6423,23 @@ struct vsir_validator_instruction_desc
static const struct vsir_validator_instruction_desc vsir_validator_instructions[] =
{
- [VKD3DSIH_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps},
- [VKD3DSIH_ELSE] = {0, 0, vsir_validate_else},
- [VKD3DSIH_ENDIF] = {0, 0, vsir_validate_endif},
- [VKD3DSIH_ENDLOOP] = {0, 0, vsir_validate_endloop},
- [VKD3DSIH_ENDREP] = {0, 0, vsir_validate_endrep},
- [VKD3DSIH_IF] = {0, 1, vsir_validate_if},
- [VKD3DSIH_IFC] = {0, 2, vsir_validate_ifc},
- [VKD3DSIH_LOOP] = {0, ~0u, vsir_validate_loop},
- [VKD3DSIH_REP] = {0, 1, vsir_validate_rep},
+ [VKD3DSIH_BRANCH] = {0, ~0u, vsir_validate_branch},
+ [VKD3DSIH_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps},
+ [VKD3DSIH_ELSE] = {0, 0, vsir_validate_else},
+ [VKD3DSIH_ENDIF] = {0, 0, vsir_validate_endif},
+ [VKD3DSIH_ENDLOOP] = {0, 0, vsir_validate_endloop},
+ [VKD3DSIH_ENDREP] = {0, 0, vsir_validate_endrep},
+ [VKD3DSIH_ENDSWITCH] = {0, 0, vsir_validate_endswitch},
+ [VKD3DSIH_IF] = {0, 1, vsir_validate_if},
+ [VKD3DSIH_IFC] = {0, 2, vsir_validate_ifc},
+ [VKD3DSIH_LABEL] = {0, 1, vsir_validate_label},
+ [VKD3DSIH_LOOP] = {0, ~0u, vsir_validate_loop},
+ [VKD3DSIH_NOP] = {0, 0, vsir_validate_nop},
+ [VKD3DSIH_PHI] = {1, ~0u, vsir_validate_phi},
+ [VKD3DSIH_REP] = {0, 1, vsir_validate_rep},
+ [VKD3DSIH_RET] = {0, 0, vsir_validate_ret},
+ [VKD3DSIH_SWITCH] = {0, 1, vsir_validate_switch},
+ [VKD3DSIH_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic},
};
static void vsir_validate_instruction(struct validation_context *ctx)
@@ -6413,185 +6599,6 @@ static void vsir_validate_instruction(struct validation_context *ctx)
desc->validate(ctx, instruction);
}
}
-
- switch (instruction->opcode)
- {
- case VKD3DSIH_SWITCH:
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validate_dst_count(ctx, instruction, 0);
- vsir_validate_src_count(ctx, instruction, 1);
- if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
- return;
- ctx->blocks[ctx->depth++] = instruction->opcode;
- break;
-
- case VKD3DSIH_ENDSWITCH:
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validate_dst_count(ctx, instruction, 0);
- vsir_validate_src_count(ctx, instruction, 0);
- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDSWITCH instruction doesn't terminate SWITCH block.");
- else
- --ctx->depth;
- break;
-
- case VKD3DSIH_RET:
- vsir_validate_dst_count(ctx, instruction, 0);
- vsir_validate_src_count(ctx, instruction, 0);
- break;
-
- case VKD3DSIH_LABEL:
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
- vsir_validate_dst_count(ctx, instruction, 0);
- vsir_validate_src_count(ctx, instruction, 1);
- if (instruction->src_count >= 1 && !vsir_register_is_label(&instruction->src[0].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid register of type %#x in a LABEL instruction, expected LABEL.",
- instruction->src[0].reg.type);
- break;
-
- case VKD3DSIH_BRANCH:
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
- vsir_validate_dst_count(ctx, instruction, 0);
- if (!vsir_validate_src_min_count(ctx, instruction, 1))
- break;
- if (vsir_register_is_label(&instruction->src[0].reg))
- {
- /* Unconditional branch: parameters are jump label,
- * optional merge label, optional continue label. */
- vsir_validate_src_max_count(ctx, instruction, 3);
-
- for (i = 0; i < instruction->src_count; ++i)
- {
- if (!vsir_register_is_label(&instruction->src[i].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid register of type %#x in unconditional BRANCH instruction, expected LABEL.",
- instruction->src[i].reg.type);
- }
- }
- else
- {
- /* Conditional branch: parameters are condition, true
- * jump label, false jump label, optional merge label,
- * optional continue label. */
- vsir_validate_src_min_count(ctx, instruction, 3);
- vsir_validate_src_max_count(ctx, instruction, 5);
-
- for (i = 1; i < instruction->src_count; ++i)
- {
- if (!vsir_register_is_label(&instruction->src[i].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid register of type %#x in conditional BRANCH instruction, expected LABEL.",
- instruction->src[i].reg.type);
- }
- }
- break;
-
- case VKD3DSIH_SWITCH_MONOLITHIC:
- {
- unsigned int case_count;
-
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
- vsir_validate_dst_count(ctx, instruction, 0);
- /* Parameters are source, default label, merge label and
- * then pairs of constant value and case label. */
- if (!vsir_validate_src_min_count(ctx, instruction, 3))
- break;
- if (instruction->src_count % 2 != 1)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.",
- instruction->src_count);
-
- if (!vsir_register_is_label(&instruction->src[1].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid default label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
- instruction->src[1].reg.type);
-
- if (!vsir_register_is_label(&instruction->src[2].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid merge label register of type %#x in monolithic SWITCH instruction, expected LABEL.",
- instruction->src[2].reg.type);
-
- case_count = (instruction->src_count - 3) / 2;
-
- for (i = 0; i < case_count; ++i)
- {
- unsigned int value_idx = 3 + 2 * i;
- unsigned int label_idx = 3 + 2 * i + 1;
-
- if (!register_is_constant(&instruction->src[value_idx].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid value register for case %zu of type %#x in monolithic SWITCH instruction, "
- "expected IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
-
- if (!vsir_register_is_label(&instruction->src[label_idx].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid label register for case %zu of type %#x in monolithic SWITCH instruction, "
- "expected LABEL.", i, instruction->src[value_idx].reg.type);
- }
- break;
- }
-
- case VKD3DSIH_PHI:
- {
- unsigned int incoming_count;
-
- vsir_validate_cf_type(ctx, instruction, VSIR_CF_BLOCKS);
- vsir_validate_dst_count(ctx, instruction, 1);
- vsir_validate_src_min_count(ctx, instruction, 2);
- if (instruction->src_count % 2 != 0)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for a PHI instruction, it must be an even number.",
- instruction->src_count);
- incoming_count = instruction->src_count / 2;
-
- if (!register_is_ssa(&instruction->dst[0].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid destination of type %#x in PHI instruction, expected SSA.",
- instruction->dst[0].reg.type);
-
- if (instruction->dst[0].reg.dimension != VSIR_DIMENSION_SCALAR)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
- "Invalid destination dimension %#x in PHI instruction, expected scalar.",
- instruction->dst[0].reg.dimension);
-
- if (instruction->dst[0].modifiers != VKD3DSPDM_NONE)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS,
- "Invalid modifiers %#x for the destination of a PHI instruction, expected none.",
- instruction->dst[0].modifiers);
-
- if (instruction->dst[0].shift != 0)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT,
- "Invalid shift %#x for the destination of a PHI instruction, expected none.",
- instruction->dst[0].shift);
-
- for (i = 0; i < incoming_count; ++i)
- {
- unsigned int value_idx = 2 * i;
- unsigned int label_idx = 2 * i + 1;
-
- if (!register_is_constant_or_undef(&instruction->src[value_idx].reg)
- && !register_is_ssa(&instruction->src[value_idx].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid value register for incoming %zu of type %#x in PHI instruction, "
- "expected SSA, IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
-
- if (instruction->src[value_idx].reg.dimension != VSIR_DIMENSION_SCALAR)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
- "Invalid value dimension %#x for incoming %zu in PHI instruction, expected scalar.",
- instruction->src[value_idx].reg.dimension, i);
-
- if (!vsir_register_is_label(&instruction->src[label_idx].reg))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
- "Invalid label register for case %zu of type %#x in PHI instruction, "
- "expected LABEL.", i, instruction->src[value_idx].reg.type);
- }
- break;
- }
-
- default:
- break;
- }
}
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
@@ -6710,7 +6717,6 @@ enum vkd3d_result vsir_program_transform(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 (compile_info->target_type != VKD3D_SHADER_TARGET_GLSL
&& compile_info->target_type != VKD3D_SHADER_TARGET_MSL)
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 8866780132e..8146a393a4c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -165,6 +165,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT = 5303,
VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304,
VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305,
+ VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,
--
2.45.2