You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
1951 lines
84 KiB
Diff
1951 lines
84 KiB
Diff
From baab59667d933fe15af4b456ea994d7aaf489d27 Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Fri, 15 Aug 2025 07:48:03 +1000
|
|
Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17.
|
|
|
|
---
|
|
libs/vkd3d/include/vkd3d_shader.h | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +-
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 5 +-
|
|
libs/vkd3d/libs/vkd3d-shader/glsl.c | 3 +
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 122 +++--
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 24 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 27 +-
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 418 +++++++++++-------
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 100 +++--
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 161 +++++--
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 51 ++-
|
|
12 files changed, 607 insertions(+), 325 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index b50271ce9bb..0fd3c67b7e0 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -2966,6 +2966,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver
|
|
* - VKD3D_SHADER_SOURCE_DXBC_DXIL
|
|
* - VKD3D_SHADER_SOURCE_DXBC_TPF
|
|
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE
|
|
+ * - VKD3D_SHADER_SOURCE_HLSL
|
|
*
|
|
* \param compile_info A chained structure containing scan parameters.
|
|
* \n
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
index 2ec9a74249b..6425a8f62d2 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -1961,7 +1961,7 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler,
|
|
}
|
|
|
|
enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_code *out, enum vsir_asm_flags flags)
|
|
+ struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
const struct vkd3d_shader_version *shader_version = &program->shader_version;
|
|
enum vkd3d_shader_compile_option_formatting_flags formatting;
|
|
@@ -2029,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd
|
|
if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4)
|
|
compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES;
|
|
|
|
+ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS)
|
|
+ {
|
|
+ if ((result = vsir_allocate_temp_registers(program, message_context)) < 0)
|
|
+ return result;
|
|
+ if ((result = vsir_update_dcl_temps(program, message_context)))
|
|
+ return result;
|
|
+ }
|
|
+
|
|
buffer = &compiler.buffer;
|
|
vkd3d_string_buffer_init(buffer);
|
|
|
|
@@ -2250,17 +2258,22 @@ void vsir_program_trace(struct vsir_program *program)
|
|
{
|
|
const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES
|
|
| VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS;
|
|
+ struct vkd3d_shader_message_context message_context;
|
|
struct vkd3d_shader_code code;
|
|
const char *p, *q, *end;
|
|
|
|
+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE);
|
|
+
|
|
trace_signature(&program->input_signature, "Input");
|
|
trace_signature(&program->output_signature, "Output");
|
|
trace_signature(&program->patch_constant_signature, "Patch-constant");
|
|
trace_io_declarations(program);
|
|
|
|
- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK)
|
|
+ if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK)
|
|
return;
|
|
|
|
+ vkd3d_shader_message_context_cleanup(&message_context);
|
|
+
|
|
end = (const char *)code.code + code.size;
|
|
for (p = code.code; p < end; p = q)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index dd13757bf59..751e5578276 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -1513,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
|
|
return ret;
|
|
}
|
|
|
|
- return VKD3D_OK;
|
|
+ if (program->normalisation_level >= VSIR_NORMALISED_SM4)
|
|
+ ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name,
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
index e57a4aa2731..dfe0a40ddf0 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
@@ -2444,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags,
|
|
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
|
|
return ret;
|
|
|
|
+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0)
|
|
+ return ret;
|
|
+
|
|
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6);
|
|
VKD3D_ASSERT(program->has_descriptor_info);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index 3199072275b..62335086e20 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -4897,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
|
|
hlsl_release_string_buffer(ctx, name);
|
|
}
|
|
|
|
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
|
|
- const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context)
|
|
+static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files,
|
|
+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile,
|
|
+ struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
unsigned int i;
|
|
|
|
@@ -4908,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
|
|
ctx->message_context = message_context;
|
|
|
|
- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files))))
|
|
- return false;
|
|
- if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : "<anonymous>")))
|
|
- {
|
|
- vkd3d_free(ctx->source_files);
|
|
+ ctx->source_files = source_files;
|
|
+ if (!vkd3d_shader_source_list_append(source_files,
|
|
+ compile_info->source_name ? compile_info->source_name : "<anonymous>"))
|
|
return false;
|
|
- }
|
|
- ctx->source_files_count = 1;
|
|
- ctx->location.source_name = ctx->source_files[0];
|
|
+
|
|
+ ctx->location.source_name = source_files->sources[0];
|
|
ctx->location.line = ctx->location.column = 1;
|
|
vkd3d_string_buffer_cache_init(&ctx->string_buffers);
|
|
|
|
@@ -4924,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
|
|
if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL)))
|
|
{
|
|
- vkd3d_free((void *)ctx->source_files[0]);
|
|
- vkd3d_free(ctx->source_files);
|
|
+ vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers);
|
|
return false;
|
|
}
|
|
hlsl_push_scope(ctx);
|
|
@@ -5010,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
|
|
struct hlsl_type *type, *next_type;
|
|
unsigned int i;
|
|
|
|
- for (i = 0; i < ctx->source_files_count; ++i)
|
|
- vkd3d_free((void *)ctx->source_files[i]);
|
|
- vkd3d_free(ctx->source_files);
|
|
vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers);
|
|
|
|
rb_destroy(&ctx->functions, free_function_rb, NULL);
|
|
@@ -5054,26 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
|
|
vkd3d_free(ctx->constant_defs.regs);
|
|
}
|
|
|
|
-static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
|
|
+static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list,
|
|
+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile,
|
|
struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
enum vkd3d_shader_target_type target_type = compile_info->target_type;
|
|
- const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
|
|
- const struct hlsl_profile_info *profile;
|
|
int ret;
|
|
|
|
- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
|
|
- {
|
|
- ERR("No HLSL source info given.\n");
|
|
- return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
- }
|
|
-
|
|
- if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
|
|
- {
|
|
- FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile));
|
|
- return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
- }
|
|
-
|
|
if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT)
|
|
{
|
|
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
@@ -5099,7 +5080,7 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
- if (!hlsl_ctx_init(ctx, compile_info, profile, message_context))
|
|
+ if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2)
|
|
@@ -5128,35 +5109,85 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info,
|
|
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out)
|
|
{
|
|
+ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
|
|
+ struct vkd3d_shader_source_list source_list;
|
|
+ const struct hlsl_profile_info *profile;
|
|
struct hlsl_ctx ctx;
|
|
int ret;
|
|
|
|
- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0)
|
|
+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
|
|
+ {
|
|
+ WARN("No HLSL source info given.\n");
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE,
|
|
+ "Unknown target profile '%s'.", hlsl_source_info->profile);
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+
|
|
+ vkd3d_shader_source_list_init(&source_list);
|
|
+ if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0)
|
|
+ {
|
|
+ vkd3d_shader_source_list_cleanup(&source_list);
|
|
return ret;
|
|
+ }
|
|
|
|
ret = hlsl_emit_effect_binary(&ctx, out);
|
|
hlsl_ctx_cleanup(&ctx);
|
|
+ vkd3d_shader_source_list_cleanup(&source_list);
|
|
|
|
return ret;
|
|
}
|
|
|
|
-int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out)
|
|
+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
|
|
+ struct vkd3d_shader_message_context *message_context,
|
|
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data)
|
|
{
|
|
const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
|
|
- uint64_t config_flags = vkd3d_shader_init_config_flags();
|
|
struct hlsl_ir_function_decl *decl, *entry_func = NULL;
|
|
- struct vkd3d_shader_code reflection_data = {0};
|
|
+ enum vsir_normalisation_level normalisation_level;
|
|
+ const struct hlsl_profile_info *profile;
|
|
+ struct vkd3d_shader_version version;
|
|
struct hlsl_ir_function *func;
|
|
- struct vsir_program program;
|
|
const char *entry_point;
|
|
struct hlsl_ctx ctx;
|
|
int ret;
|
|
|
|
- if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0)
|
|
+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
|
|
+ {
|
|
+ WARN("No HLSL source info given.\n");
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE,
|
|
+ "Unknown target profile '%s'.", hlsl_source_info->profile);
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+
|
|
+ version = (struct vkd3d_shader_version)
|
|
+ {
|
|
+ .type = profile->type,
|
|
+ .major = profile->major_version,
|
|
+ .minor = profile->minor_version,
|
|
+ };
|
|
+ normalisation_level = VSIR_NORMALISED_SM4;
|
|
+ if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM
|
|
+ || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE))
|
|
+ normalisation_level = VSIR_NORMALISED_SM1;
|
|
+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0)
|
|
+ {
|
|
+ vsir_program_cleanup(program);
|
|
return ret;
|
|
+ }
|
|
|
|
- hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO);
|
|
entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main";
|
|
if ((func = hlsl_get_function(&ctx, entry_point)))
|
|
{
|
|
@@ -5181,17 +5212,16 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info,
|
|
hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED,
|
|
"Entry point \"%s\" is not defined.", entry_point);
|
|
hlsl_ctx_cleanup(&ctx);
|
|
+ vsir_program_cleanup(program);
|
|
return VKD3D_ERROR_INVALID_SHADER;
|
|
}
|
|
|
|
- if ((ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, &program, &reflection_data)) >= 0)
|
|
- {
|
|
- vsir_program_trace(&program);
|
|
- ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, message_context);
|
|
- vkd3d_shader_free_shader_code(&reflection_data);
|
|
- vsir_program_cleanup(&program);
|
|
- }
|
|
+ ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data);
|
|
hlsl_ctx_cleanup(&ctx);
|
|
+ if (ret < 0)
|
|
+ vsir_program_cleanup(program);
|
|
+ else
|
|
+ vsir_program_trace(program);
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index c3002258aa2..d67f820fe8b 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -1093,8 +1093,7 @@ struct hlsl_ctx
|
|
{
|
|
const struct hlsl_profile_info *profile;
|
|
|
|
- const char **source_files;
|
|
- unsigned int source_files_count;
|
|
+ struct vkd3d_shader_source_list *source_files;
|
|
/* Current location being read in the HLSL source, updated while parsing. */
|
|
struct vkd3d_shader_location location;
|
|
/* Stores the logging messages and logging configuration. */
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index 66582e884fe..024d96c5663 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -7190,23 +7190,19 @@ declaration_statement_list:
|
|
preproc_directive:
|
|
PRE_LINE STRING
|
|
{
|
|
- const char **new_array = NULL;
|
|
-
|
|
- ctx->location.line = $1;
|
|
if (strcmp($2, ctx->location.source_name))
|
|
- new_array = hlsl_realloc(ctx, ctx->source_files,
|
|
- sizeof(*ctx->source_files) * (ctx->source_files_count + 1));
|
|
-
|
|
- if (new_array)
|
|
- {
|
|
- ctx->source_files = new_array;
|
|
- ctx->source_files[ctx->source_files_count++] = $2;
|
|
- ctx->location.source_name = $2;
|
|
- }
|
|
- else
|
|
{
|
|
- vkd3d_free($2);
|
|
+ if (!vkd3d_shader_source_list_append(ctx->source_files, $2))
|
|
+ {
|
|
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ ctx->location.line = $1;
|
|
+ ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1];
|
|
+ }
|
|
}
|
|
+ vkd3d_free($2);
|
|
}
|
|
|
|
struct_declaration_without_vars:
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index dbda72eb30f..0b3dee4d2ce 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -9945,6 +9945,11 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co
|
|
sm1_generate_vsir_block(ctx, body, program);
|
|
|
|
program->ssa_count = ctx->ssa_count;
|
|
+
|
|
+ if (ctx->result)
|
|
+ return;
|
|
+ if (program->normalisation_level >= VSIR_NORMALISED_SM4)
|
|
+ ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context);
|
|
}
|
|
|
|
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
|
|
@@ -14272,7 +14277,6 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info
|
|
uint32_t config_flags = vkd3d_shader_init_config_flags();
|
|
const struct hlsl_profile_info *profile = ctx->profile;
|
|
struct list semantic_vars, patch_semantic_vars;
|
|
- struct vkd3d_shader_version version = {0};
|
|
struct hlsl_ir_var *var;
|
|
|
|
parse_entry_function_attributes(ctx, entry_func);
|
|
@@ -14349,39 +14353,24 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info
|
|
if (ctx->result)
|
|
return ctx->result;
|
|
|
|
- version.major = ctx->profile->major_version;
|
|
- version.minor = ctx->profile->minor_version;
|
|
- version.type = ctx->profile->type;
|
|
- if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4))
|
|
- {
|
|
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- return ctx->result;
|
|
- }
|
|
-
|
|
generate_vsir_signature(ctx, program, entry_func, &semantic_vars);
|
|
- if (version.type == VKD3D_SHADER_TYPE_HULL)
|
|
+ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
|
|
generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars);
|
|
|
|
- if (version.major < 4)
|
|
+ if (program->shader_version.major < 4)
|
|
sm1_generate_ctab(ctx, reflection_data);
|
|
else
|
|
sm4_generate_rdef(ctx, reflection_data);
|
|
if (ctx->result)
|
|
- {
|
|
- vsir_program_cleanup(program);
|
|
return ctx->result;
|
|
- }
|
|
|
|
- if (version.major < 4)
|
|
+ if (program->shader_version.major < 4)
|
|
sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program);
|
|
else
|
|
sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body,
|
|
&patch_semantic_vars, &patch_body, config_flags, program);
|
|
if (ctx->result)
|
|
- {
|
|
vkd3d_shader_free_shader_code(reflection_data);
|
|
- vsir_program_cleanup(program);
|
|
- }
|
|
|
|
return ctx->result;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 9d93936ac9e..23e059a3490 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -451,6 +451,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c
|
|
return false;
|
|
}
|
|
|
|
+ vkd3d_shader_source_list_init(&program->source_files);
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -463,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program)
|
|
for (i = 0; i < program->block_name_count; ++i)
|
|
vkd3d_free((void *)program->block_names[i]);
|
|
vkd3d_free(program->block_names);
|
|
+ vkd3d_shader_source_list_cleanup(&program->source_files);
|
|
shader_instruction_array_destroy(&program->instructions);
|
|
shader_signature_cleanup(&program->input_signature);
|
|
shader_signature_cleanup(&program->output_signature);
|
|
@@ -1387,6 +1390,53 @@ static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *prog
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program,
|
|
+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
|
|
+{
|
|
+ /* texcrd DST, t# -> mov DST, t# */
|
|
+
|
|
+ if (ins->src[0].modifiers)
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
+ "Aborting due to not yet implemented feature: texcrd source modifier.");
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+
|
|
+ ins->opcode = VSIR_OP_MOV;
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
+static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program,
|
|
+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
|
|
+{
|
|
+ unsigned int idx = ins->src[0].reg.idx[0].offset;
|
|
+ struct vkd3d_shader_src_param *srcs;
|
|
+
|
|
+ /* texld DST, t# -> sample DST, t#, resource#, sampler# */
|
|
+
|
|
+ if (ins->src[0].modifiers)
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
+ "Aborting due to not yet implemented feature: texld source modifier.");
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+
|
|
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ /* Note we run before I/O normalization. */
|
|
+ srcs[0] = ins->src[0];
|
|
+ vsir_src_param_init_resource(&srcs[1], idx, idx);
|
|
+ vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
|
+
|
|
+ ins->opcode = VSIR_OP_SAMPLE;
|
|
+ ins->src = srcs;
|
|
+ ins->src_count = 3;
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
|
|
struct vsir_program_iterator *it, unsigned int *tmp_idx)
|
|
{
|
|
@@ -1605,6 +1655,45 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program,
|
|
+ struct vsir_transformation_context *ctx)
|
|
+{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
+ struct vkd3d_shader_message_context *message_context = ctx->message_context;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+ unsigned int tmp_idx = ~0u;
|
|
+
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
+ {
|
|
+ enum vkd3d_result ret;
|
|
+
|
|
+ switch (ins->opcode)
|
|
+ {
|
|
+ case VSIR_OP_TEXCRD:
|
|
+ ret = vsir_program_lower_texcrd(program, ins, message_context);
|
|
+ break;
|
|
+
|
|
+ case VSIR_OP_TEXLD:
|
|
+ if (program->shader_version.major == 1)
|
|
+ ret = vsir_program_lower_texld_sm1(program, ins, message_context);
|
|
+ else if (ins->flags == VKD3DSI_TEXLD_PROJECT)
|
|
+ ret = vsir_program_lower_texldp(program, &it, &tmp_idx);
|
|
+ else
|
|
+ ret = vsir_program_lower_texld(program, ins, message_context);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ ret = VKD3D_OK;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
@@ -1688,19 +1777,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
|
}
|
|
break;
|
|
|
|
- case VSIR_OP_TEXLD:
|
|
- if (ins->flags == VKD3DSI_TEXLD_PROJECT)
|
|
- {
|
|
- if ((ret = vsir_program_lower_texldp(program, &it, &tmp_idx)) < 0)
|
|
- return ret;
|
|
- }
|
|
- else
|
|
- {
|
|
- if ((ret = vsir_program_lower_texld(program, ins, message_context)) < 0)
|
|
- return ret;
|
|
- }
|
|
- break;
|
|
-
|
|
case VSIR_OP_TEXLDD:
|
|
if ((ret = vsir_program_lower_texldd(program, ins)) < 0)
|
|
return ret;
|
|
@@ -1714,7 +1790,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
|
case VSIR_OP_TEXBEM:
|
|
case VSIR_OP_TEXBEML:
|
|
case VSIR_OP_TEXCOORD:
|
|
- case VSIR_OP_TEXCRD:
|
|
case VSIR_OP_TEXDEPTH:
|
|
case VSIR_OP_TEXDP3:
|
|
case VSIR_OP_TEXDP3TEX:
|
|
@@ -1762,6 +1837,39 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program,
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0.
|
|
+ * We don't need to modify the signature since it already contains COLOR. */
|
|
+static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program,
|
|
+ struct vsir_transformation_context *ctx)
|
|
+{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+ struct vkd3d_shader_location loc;
|
|
+
|
|
+ if (!(ins = vsir_program_iterator_tail(&it)))
|
|
+ return VKD3D_OK;
|
|
+ loc = ins->location;
|
|
+
|
|
+ if (!(ins = vsir_program_append(program)))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1))
|
|
+ {
|
|
+ vsir_instruction_init(ins, &loc, VSIR_OP_NOP);
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ }
|
|
+
|
|
+ src_param_init_temp_float4(&ins->src[0], 0);
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
+ /* Note we run before I/O normalization. */
|
|
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1);
|
|
+ ins->dst[0].reg.idx[0].offset = 0;
|
|
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
|
|
+ ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
static struct signature_element *add_signature_element(struct shader_signature *signature,
|
|
const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index,
|
|
enum vkd3d_shader_interpolation_mode interpolation_mode)
|
|
@@ -1814,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr
|
|
static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
static const struct vkd3d_shader_location no_loc;
|
|
struct vkd3d_shader_instruction *ins;
|
|
unsigned int i;
|
|
@@ -1825,17 +1934,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra
|
|
/* Write the instruction after all LABEL, DCL, and NOP instructions.
|
|
* We need to skip NOP instructions because they might result from removed
|
|
* DCLs, and there could still be DCLs after NOPs. */
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP)
|
|
break;
|
|
}
|
|
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, i, 1))
|
|
+ vsir_program_iterator_prev(&it);
|
|
+ if (!vsir_program_iterator_insert_after(&it, 1))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ins = &program->instructions.elements[i];
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
|
|
vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
|
|
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1);
|
|
@@ -1936,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name};
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
struct vkd3d_shader_message_context *message_context = ctx->message_context;
|
|
const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info;
|
|
bool allows_subset_masks = target_allows_subset_masks(compile_info);
|
|
@@ -1945,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
struct signature_element *new_elements, *e;
|
|
unsigned int uninit_varying_count = 0;
|
|
unsigned int subset_varying_count = 0;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
unsigned int new_register_count = 0;
|
|
unsigned int i;
|
|
|
|
@@ -2044,18 +2154,18 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
}
|
|
|
|
/* Write each uninitialized varying before each ret. */
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
struct vkd3d_shader_location loc;
|
|
|
|
if (ins->opcode != VSIR_OP_RET)
|
|
continue;
|
|
|
|
loc = ins->location;
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count))
|
|
+ vsir_program_iterator_prev(&it);
|
|
+ if (!vsir_program_iterator_insert_after(&it, uninit_varying_count))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ins = &program->instructions.elements[i];
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
|
|
for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j)
|
|
{
|
|
@@ -2065,10 +2175,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask);
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
- ++ins;
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
}
|
|
-
|
|
- i += uninit_varying_count;
|
|
}
|
|
|
|
/* Vulkan (without KHR_maintenance4) disallows any mismatching masks,
|
|
@@ -2079,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
if (!subset_varying_count || allows_subset_masks)
|
|
return VKD3D_OK;
|
|
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
-
|
|
for (unsigned int j = 0; j < ins->dst_count; ++j)
|
|
remove_unread_output_components(signature, ins, &ins->dst[j]);
|
|
}
|
|
@@ -2121,10 +2227,9 @@ struct shader_phase_location_array
|
|
unsigned int count;
|
|
};
|
|
|
|
-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser,
|
|
- unsigned int index, struct shader_phase_location_array *locations)
|
|
+static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index,
|
|
+ struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations)
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &normaliser->program->instructions.elements[index];
|
|
struct shader_phase_location *loc;
|
|
bool b;
|
|
|
|
@@ -2289,15 +2394,19 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali
|
|
static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
struct shader_phase_location_array locations;
|
|
struct hull_flattener flattener = {program};
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
enum vkd3d_result result = VKD3D_OK;
|
|
unsigned int i;
|
|
|
|
flattener.phase = VSIR_OP_INVALID;
|
|
- for (i = 0, locations.count = 0; i < instructions->count; ++i)
|
|
- flattener_eliminate_phase_related_dcls(&flattener, i, &locations);
|
|
+ locations.count = 0;
|
|
+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i)
|
|
+ {
|
|
+ flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations);
|
|
+ }
|
|
bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID);
|
|
bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID);
|
|
|
|
@@ -2315,10 +2424,9 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro
|
|
|
|
if (flattener.phase != VSIR_OP_INVALID)
|
|
{
|
|
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
|
|
+ if (!(ins = vsir_program_append(program)))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- vsir_instruction_init(&instructions->elements[instructions->count++],
|
|
- &flattener.last_ret_location, VSIR_OP_RET);
|
|
+ vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET);
|
|
}
|
|
|
|
return result;
|
|
@@ -2436,11 +2544,11 @@ 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_transformation_context *ctx)
|
|
{
|
|
- struct vkd3d_shader_instruction_array *instructions;
|
|
struct control_point_normaliser normaliser;
|
|
unsigned int input_control_point_count;
|
|
struct vkd3d_shader_location location;
|
|
struct vkd3d_shader_instruction *ins;
|
|
+ struct vsir_program_iterator it;
|
|
enum vkd3d_result ret;
|
|
unsigned int i, j;
|
|
|
|
@@ -2458,13 +2566,11 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
normaliser.instructions = program->instructions;
|
|
- instructions = &normaliser.instructions;
|
|
+ it = vsir_program_iterator(&normaliser.instructions);
|
|
normaliser.phase = VSIR_OP_INVALID;
|
|
|
|
- for (i = 0; i < normaliser.instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &instructions->elements[i];
|
|
-
|
|
switch (ins->opcode)
|
|
{
|
|
case VSIR_OP_HS_CONTROL_POINT_PHASE:
|
|
@@ -2484,10 +2590,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
normaliser.phase = VSIR_OP_INVALID;
|
|
input_control_point_count = 1;
|
|
|
|
- for (i = 0; i < instructions->count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i)
|
|
{
|
|
- ins = &instructions->elements[i];
|
|
-
|
|
switch (ins->opcode)
|
|
{
|
|
case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT:
|
|
@@ -2531,7 +2635,6 @@ struct io_normaliser
|
|
{
|
|
struct vkd3d_shader_message_context *message_context;
|
|
enum vkd3d_result result;
|
|
- struct vkd3d_shader_instruction_array instructions;
|
|
enum vkd3d_shader_type shader_type;
|
|
uint8_t major;
|
|
struct shader_signature *input_signature;
|
|
@@ -3147,10 +3250,10 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
- struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK, program->instructions};
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
+ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK};
|
|
struct vkd3d_shader_instruction *ins;
|
|
enum vkd3d_result ret;
|
|
- unsigned int i;
|
|
|
|
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO);
|
|
|
|
@@ -3161,10 +3264,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program
|
|
normaliser.output_signature = &program->output_signature;
|
|
normaliser.patch_constant_signature = &program->patch_constant_signature;
|
|
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
switch (ins->opcode)
|
|
{
|
|
case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT:
|
|
@@ -3190,16 +3291,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program
|
|
normaliser.output_range_map, false)) < 0
|
|
|| (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature,
|
|
normaliser.pc_range_map, true)) < 0)
|
|
- {
|
|
- program->instructions = normaliser.instructions;
|
|
return ret;
|
|
- }
|
|
|
|
normaliser.phase = VSIR_OP_INVALID;
|
|
- for (i = 0; i < normaliser.instructions.count; ++i)
|
|
- shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser);
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
+ {
|
|
+ shader_instruction_normalise_io_params(ins, &normaliser);
|
|
+ }
|
|
|
|
- program->instructions = normaliser.instructions;
|
|
program->use_vocp = normaliser.use_vocp;
|
|
program->normalisation_level = VSIR_NORMALISED_SM6;
|
|
return normaliser.result;
|
|
@@ -3288,13 +3387,13 @@ 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_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
struct flat_constants_normaliser normaliser = {0};
|
|
- unsigned int i, j;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+ unsigned int i;
|
|
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
-
|
|
if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB)
|
|
{
|
|
struct flat_constant_def *def;
|
|
@@ -3309,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
|
|
def = &normaliser.defs[normaliser.def_count++];
|
|
|
|
get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL);
|
|
- for (j = 0; j < 4; ++j)
|
|
- def->value[j] = ins->src[0].reg.u.immconst_u32[j];
|
|
+ for (i = 0; i < 4; ++i)
|
|
+ {
|
|
+ def->value[i] = ins->src[0].reg.u.immconst_u32[i];
|
|
+ }
|
|
|
|
vkd3d_shader_instruction_make_nop(ins);
|
|
}
|
|
else
|
|
{
|
|
- for (j = 0; j < ins->src_count; ++j)
|
|
- shader_register_normalise_flat_constants(&ins->src[j], &normaliser);
|
|
+ for (i = 0; i < ins->src_count; ++i)
|
|
+ {
|
|
+ shader_register_normalise_flat_constants(&ins->src[i], &normaliser);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -3328,13 +3431,13 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
|
|
static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
- size_t i, depth = 0;
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
bool dead = false;
|
|
+ size_t depth = 0;
|
|
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
-
|
|
switch (ins->opcode)
|
|
{
|
|
case VSIR_OP_IF:
|
|
@@ -3707,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
|
struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
struct vkd3d_shader_instruction_array *instructions;
|
|
+ const struct vkd3d_shader_instruction *instruction;
|
|
struct vsir_program *program = flattener->program;
|
|
bool is_hull_shader, after_declarations_section;
|
|
struct vkd3d_shader_instruction *dst_ins;
|
|
- size_t i;
|
|
+ struct vsir_program_iterator it;
|
|
|
|
instructions = &program->instructions;
|
|
is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL;
|
|
@@ -3719,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
|
if (!cf_flattener_require_space(flattener, instructions->count + 1))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
- for (i = 0; i < instructions->count; ++i)
|
|
+ it = vsir_program_iterator(instructions);
|
|
+ for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it))
|
|
{
|
|
unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id;
|
|
- const struct vkd3d_shader_instruction *instruction = &instructions->elements[i];
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
struct cf_flattener_info *cf_info;
|
|
|
|
@@ -4321,10 +4425,12 @@ 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_transformation_context *ctx)
|
|
{
|
|
- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i;
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
+ size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count;
|
|
struct ssas_to_temps_block_info *info, *block_info = NULL;
|
|
struct vkd3d_shader_instruction *instructions = NULL;
|
|
struct ssas_to_temps_alloc alloc = {0};
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
unsigned int current_label = 0;
|
|
|
|
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
|
|
@@ -4338,9 +4444,10 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count))
|
|
goto fail;
|
|
|
|
- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i)
|
|
+ phi_count = 0;
|
|
+ incoming_count = 0;
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
unsigned int j, temp_idx;
|
|
|
|
/* Only phi src/dst SSA values need be converted here. Structurisation may
|
|
@@ -4383,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count))
|
|
goto fail;
|
|
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i];
|
|
+ struct vkd3d_shader_instruction *mov_ins;
|
|
size_t j;
|
|
|
|
for (j = 0; j < ins->dst_count; ++j)
|
|
@@ -6826,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr
|
|
}
|
|
|
|
static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program,
|
|
- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func,
|
|
+ struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func,
|
|
const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx,
|
|
- uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context)
|
|
+ uint32_t colour_temp, struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
- const struct vkd3d_shader_location loc = ret->location;
|
|
+ struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
|
|
static const struct vkd3d_shader_location no_loc;
|
|
- size_t pos = ret - instructions->elements;
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
static const struct
|
|
@@ -6854,23 +6959,23 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
|
|
|
|
if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
|
|
{
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
|
|
+ vsir_program_iterator_prev(it);
|
|
+ if (!vsir_program_iterator_insert_after(it, 1))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ret = NULL;
|
|
- ins = &program->instructions.elements[pos];
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1);
|
|
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
src_param_init_const_uint(&ins->src[0], 0);
|
|
+ vsir_program_iterator_next(it);
|
|
|
|
- *ret_pos = pos + 1;
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3))
|
|
+ vsir_program_iterator_prev(it);
|
|
+ if (!vsir_program_iterator_insert_after(it, 3))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ret = NULL;
|
|
- ins = &program->instructions.elements[pos];
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
switch (ref->data_type)
|
|
{
|
|
@@ -6902,14 +7007,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
|
|
ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
|
|
|
|
- ++ins;
|
|
+ ins = vsir_program_iterator_next(it);
|
|
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1);
|
|
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
|
|
|
|
++program->ssa_count;
|
|
|
|
- ++ins;
|
|
+ ins = vsir_program_iterator_next(it);
|
|
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
|
|
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1);
|
|
ins->dst[0].reg.idx[0].offset = colour_signature_idx;
|
|
@@ -6919,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
|
|
- *ret_pos = pos + 3;
|
|
+ vsir_program_iterator_next(it);
|
|
+
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
struct vkd3d_shader_message_context *message_context = ctx->message_context;
|
|
const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL;
|
|
uint32_t colour_signature_idx, colour_temp = ~0u;
|
|
static const struct vkd3d_shader_location no_loc;
|
|
enum vkd3d_shader_comparison_func compare_func;
|
|
struct vkd3d_shader_instruction *ins;
|
|
- size_t new_pos;
|
|
int ret;
|
|
|
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
|
@@ -6969,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro
|
|
if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER)
|
|
colour_temp = program->temp_count++;
|
|
|
|
- for (size_t i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
if (vsir_instruction_is_dcl(ins))
|
|
continue;
|
|
|
|
if (ins->opcode == VSIR_OP_RET)
|
|
{
|
|
- if ((ret = insert_alpha_test_before_ret(program, ins, compare_func,
|
|
- ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
|
|
+ if ((ret = insert_alpha_test_before_ret(program, &it, compare_func,
|
|
+ ref, colour_signature_idx, colour_temp, message_context)) < 0)
|
|
return ret;
|
|
- i = new_pos;
|
|
continue;
|
|
}
|
|
|
|
@@ -7007,19 +7110,17 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro
|
|
}
|
|
|
|
static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program,
|
|
- const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx,
|
|
- uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos)
|
|
+ struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx,
|
|
+ uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx)
|
|
{
|
|
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
- const struct vkd3d_shader_location loc = ret->location;
|
|
- size_t pos = ret - instructions->elements;
|
|
+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
|
|
struct vkd3d_shader_instruction *ins;
|
|
unsigned int output_idx = 0;
|
|
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1))
|
|
+ vsir_program_iterator_prev(it);
|
|
+ if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ret = NULL;
|
|
- ins = &program->instructions.elements[pos];
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
for (unsigned int i = 0; i < 8; ++i)
|
|
{
|
|
@@ -7041,7 +7142,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog
|
|
ins->dst[0].write_mask = (1u << (output_idx % 4));
|
|
++output_idx;
|
|
|
|
- ++ins;
|
|
+ ins = vsir_program_iterator_next(it);
|
|
}
|
|
|
|
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
|
|
@@ -7052,14 +7153,15 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog
|
|
src_param_init_temp_float(&ins->src[0], position_temp);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
- *ret_pos = pos + vkd3d_popcount(mask) + 1;
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
struct shader_signature *signature = &program->output_signature;
|
|
unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u;
|
|
const struct vkd3d_shader_parameter1 *mask_parameter = NULL;
|
|
@@ -7068,7 +7170,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
|
|
struct signature_element *clip_element;
|
|
struct vkd3d_shader_instruction *ins;
|
|
unsigned int plane_count;
|
|
- size_t new_pos;
|
|
int ret;
|
|
|
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
|
|
@@ -7144,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
|
|
|
|
position_temp = program->temp_count++;
|
|
|
|
- for (size_t i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
if (vsir_instruction_is_dcl(ins))
|
|
continue;
|
|
|
|
if (ins->opcode == VSIR_OP_RET)
|
|
{
|
|
- if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx,
|
|
- position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0)
|
|
+ if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx,
|
|
+ position_temp, low_signature_idx, high_signature_idx)) < 0)
|
|
return ret;
|
|
- i = new_pos;
|
|
continue;
|
|
}
|
|
|
|
@@ -7185,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type)
|
|
}
|
|
|
|
static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program,
|
|
- const struct vkd3d_shader_instruction *ret, size_t *ret_pos)
|
|
+ struct vsir_program_iterator *it)
|
|
{
|
|
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
- const struct vkd3d_shader_location loc = ret->location;
|
|
- size_t pos = ret - instructions->elements;
|
|
+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
|
|
+ vsir_program_iterator_prev(it);
|
|
+ if (!vsir_program_iterator_insert_after(it, 1))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ret = NULL;
|
|
- ins = &program->instructions.elements[pos];
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
|
|
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
|
|
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
|
|
src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32);
|
|
+ ins = vsir_program_iterator_next(it);
|
|
|
|
- *ret_pos = pos + 1;
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
const struct vkd3d_shader_parameter1 *size_parameter = NULL;
|
|
static const struct vkd3d_shader_location no_loc;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
if (program->has_point_size)
|
|
return VKD3D_OK;
|
|
@@ -7239,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro
|
|
program->has_point_size = true;
|
|
|
|
/* Append a point size write before each ret. */
|
|
- for (size_t i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
-
|
|
if (ins->opcode == VSIR_OP_RET)
|
|
{
|
|
- size_t new_pos;
|
|
int ret;
|
|
|
|
- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0)
|
|
+ if ((ret = insert_point_size_before_ret(program, &it)) < 0)
|
|
return ret;
|
|
- i = new_pos;
|
|
}
|
|
}
|
|
|
|
@@ -7261,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL;
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
static const struct vkd3d_shader_location no_loc;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
if (!program->has_point_size)
|
|
return VKD3D_OK;
|
|
@@ -7298,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
|
|
|
|
/* Replace writes to the point size by inserting a clamp before each write. */
|
|
|
|
- for (size_t i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
|
|
const struct vkd3d_shader_location *loc;
|
|
unsigned int ssa_value;
|
|
bool clamp = false;
|
|
@@ -7324,11 +7419,11 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
|
|
if (!clamp)
|
|
continue;
|
|
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter))
|
|
+ if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ins = &program->instructions.elements[i + 1];
|
|
|
|
- loc = &program->instructions.elements[i].location;
|
|
+ loc = &vsir_program_iterator_current(&it)->location;
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
|
|
if (min_parameter)
|
|
{
|
|
@@ -7345,8 +7440,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
|
|
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
|
|
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
|
|
}
|
|
- ++ins;
|
|
- ++i;
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
}
|
|
|
|
if (max_parameter)
|
|
@@ -7356,8 +7450,7 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
|
|
src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32);
|
|
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
|
|
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
|
|
-
|
|
- ++i;
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
}
|
|
}
|
|
|
|
@@ -7435,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program,
|
|
static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program,
|
|
struct vsir_transformation_context *ctx)
|
|
{
|
|
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2;
|
|
const struct vkd3d_shader_parameter1 *sprite_parameter = NULL;
|
|
static const struct vkd3d_shader_location no_loc;
|
|
struct vkd3d_shader_instruction *ins;
|
|
bool used_texcoord = false;
|
|
unsigned int coord_temp;
|
|
- size_t i, insert_pos;
|
|
+ size_t i;
|
|
|
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
|
return VKD3D_OK;
|
|
@@ -7481,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
|
|
/* Construct the new temp after all LABEL, DCL, and NOP instructions.
|
|
* We need to skip NOP instructions because they might result from removed
|
|
* DCLs, and there could still be DCLs after NOPs. */
|
|
- for (i = 0; i < program->instructions.count; ++i)
|
|
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP)
|
|
break;
|
|
}
|
|
|
|
- insert_pos = i;
|
|
-
|
|
+ it2 = it;
|
|
/* Replace each texcoord read with a read from the point coord. */
|
|
- for (; i < program->instructions.count; ++i)
|
|
+ for (; ins; ins = vsir_program_iterator_next(&it2))
|
|
{
|
|
- ins = &program->instructions.elements[i];
|
|
-
|
|
if (vsir_instruction_is_dcl(ins))
|
|
continue;
|
|
|
|
@@ -7524,9 +7613,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
|
|
|
|
if (used_texcoord)
|
|
{
|
|
- if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2))
|
|
+ vsir_program_iterator_prev(&it);
|
|
+ if (!vsir_program_iterator_insert_after(&it, 2))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
- ins = &program->instructions.elements[insert_pos];
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
|
|
vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
|
|
dst_param_init_temp_float4(&ins->dst[0], coord_temp);
|
|
@@ -7534,14 +7624,14 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
- ++ins;
|
|
+ ins = vsir_program_iterator_next(&it);
|
|
|
|
vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
|
|
dst_param_init_temp_float4(&ins->dst[0], coord_temp);
|
|
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
- ++ins;
|
|
+ vsir_program_iterator_next(&it);
|
|
|
|
program->has_point_coord = true;
|
|
}
|
|
@@ -12045,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin
|
|
return ctx.result;
|
|
}
|
|
|
|
+enum vkd3d_result vsir_program_lower_d3dbc(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_transformation_context ctx =
|
|
+ {
|
|
+ .result = VKD3D_OK,
|
|
+ .program = program,
|
|
+ .config_flags = config_flags,
|
|
+ .compile_info = compile_info,
|
|
+ .message_context = message_context,
|
|
+ };
|
|
+
|
|
+ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions);
|
|
+ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)
|
|
+ vsir_transform(&ctx, vsir_program_normalise_ps1_output);
|
|
+
|
|
+ if (TRACE_ON())
|
|
+ vsir_program_trace(program);
|
|
+
|
|
+ return ctx.result;
|
|
+}
|
|
+
|
|
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)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 4f50eadf714..a4990d982bc 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -5676,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature
|
|
return max_row;
|
|
}
|
|
|
|
+static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_dst_param *dst)
|
|
+{
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ const struct vkd3d_shader_register *reg = &dst->reg;
|
|
+ const struct vkd3d_spirv_builtin *builtin;
|
|
+ struct vkd3d_symbol reg_symbol;
|
|
+ SpvStorageClass storage_class;
|
|
+ uint32_t write_mask, id;
|
|
+ struct rb_entry *entry;
|
|
+
|
|
+ VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr);
|
|
+ VKD3D_ASSERT(reg->idx_count < 2);
|
|
+
|
|
+ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
|
|
+ {
|
|
+ builtin = &vkd3d_output_point_size_builtin;
|
|
+ storage_class = SpvStorageClassOutput;
|
|
+ }
|
|
+ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class)))
|
|
+ {
|
|
+ FIXME("Unhandled register %#x.\n", reg->type);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /* vPrim may be declared in multiple hull shader phases. */
|
|
+ vkd3d_symbol_make_register(®_symbol, reg);
|
|
+ if ((entry = rb_get(&compiler->symbol_table, ®_symbol)))
|
|
+ return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
|
|
+
|
|
+ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0);
|
|
+ spirv_compiler_emit_register_execution_mode(compiler, reg->type);
|
|
+ spirv_compiler_emit_register_debug_name(builder, id, reg);
|
|
+
|
|
+ write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
|
|
+ vkd3d_symbol_set_register_info(®_symbol, id,
|
|
+ storage_class, builtin->component_type, write_mask);
|
|
+ reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
|
|
+
|
|
+ return spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
+}
|
|
+
|
|
static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
enum vkd3d_shader_register_type reg_type, unsigned int element_idx)
|
|
{
|
|
@@ -5684,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
const struct signature_element *signature_element;
|
|
const struct shader_signature *shader_signature;
|
|
enum vkd3d_shader_component_type component_type;
|
|
+ enum vkd3d_shader_register_type sysval_reg_type;
|
|
const struct vkd3d_spirv_builtin *builtin;
|
|
enum vkd3d_shader_sysval_semantic sysval;
|
|
uint32_t write_mask, reg_write_mask;
|
|
@@ -5708,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
if (!signature_element->used_mask)
|
|
return;
|
|
|
|
+ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic);
|
|
+ if (sysval_reg_type != VKD3DSPR_INPUT)
|
|
+ {
|
|
+ struct vkd3d_shader_dst_param dst;
|
|
+ const struct vkd3d_symbol *symbol;
|
|
+
|
|
+ vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0);
|
|
+ symbol = spirv_compiler_emit_io_register(compiler, &dst);
|
|
+
|
|
+ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx);
|
|
+ reg_symbol.id = symbol->id;
|
|
+ reg_symbol.info.reg = symbol->info.reg;
|
|
+ spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
+ return;
|
|
+ }
|
|
+
|
|
builtin = get_spirv_builtin_for_sysval(compiler, sysval);
|
|
|
|
array_sizes[0] = signature_element->register_count;
|
|
@@ -5829,47 +5888,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
}
|
|
}
|
|
|
|
-static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_dst_param *dst)
|
|
-{
|
|
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
- const struct vkd3d_shader_register *reg = &dst->reg;
|
|
- const struct vkd3d_spirv_builtin *builtin;
|
|
- struct vkd3d_symbol reg_symbol;
|
|
- SpvStorageClass storage_class;
|
|
- uint32_t write_mask, id;
|
|
- struct rb_entry *entry;
|
|
-
|
|
- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr);
|
|
- VKD3D_ASSERT(reg->idx_count < 2);
|
|
-
|
|
- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
|
|
- {
|
|
- builtin = &vkd3d_output_point_size_builtin;
|
|
- storage_class = SpvStorageClassOutput;
|
|
- }
|
|
- else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class)))
|
|
- {
|
|
- FIXME("Unhandled register %#x.\n", reg->type);
|
|
- return;
|
|
- }
|
|
-
|
|
- /* vPrim may be declared in multiple hull shader phases. */
|
|
- vkd3d_symbol_make_register(®_symbol, reg);
|
|
- if ((entry = rb_get(&compiler->symbol_table, ®_symbol)))
|
|
- return;
|
|
-
|
|
- id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0);
|
|
-
|
|
- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
|
|
- vkd3d_symbol_set_register_info(®_symbol, id,
|
|
- storage_class, builtin->component_type, write_mask);
|
|
- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
|
|
- spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
- spirv_compiler_emit_register_execution_mode(compiler, reg->type);
|
|
- spirv_compiler_emit_register_debug_name(builder, id, reg);
|
|
-}
|
|
-
|
|
static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler,
|
|
unsigned int register_idx)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index 891a33d326f..d1992c9d446 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -57,6 +57,39 @@ uint32_t vkd3d_parse_integer(const char *s)
|
|
return ret;
|
|
}
|
|
|
|
+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source)
|
|
+{
|
|
+ char *s;
|
|
+
|
|
+ if (!(s = vkd3d_strdup(source)))
|
|
+ return false;
|
|
+
|
|
+ if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources)))
|
|
+ {
|
|
+ vkd3d_free(s);
|
|
+ return false;
|
|
+ }
|
|
+ l->sources[l->count++] = s;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l)
|
|
+{
|
|
+ size_t i;
|
|
+
|
|
+ for (i = 0; i < l->count; ++i)
|
|
+ {
|
|
+ vkd3d_free((void *)l->sources[i]);
|
|
+ }
|
|
+ vkd3d_free(l->sources);
|
|
+}
|
|
+
|
|
+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l)
|
|
+{
|
|
+ memset(l, 0, sizeof(*l));
|
|
+}
|
|
+
|
|
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
|
|
{
|
|
buffer->buffer_size = 16;
|
|
@@ -767,12 +800,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_
|
|
}
|
|
|
|
static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
|
|
- struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
|
|
+ const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context,
|
|
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data)
|
|
{
|
|
+ struct vkd3d_shader_compile_info preprocessed_info;
|
|
+ struct vkd3d_shader_code preprocessed;
|
|
enum vkd3d_result ret;
|
|
|
|
switch (compile_info->source_type)
|
|
{
|
|
+ case VKD3D_SHADER_SOURCE_HLSL:
|
|
+ if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0)
|
|
+ {
|
|
+ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC);
|
|
+
|
|
+ preprocessed_info = *compile_info;
|
|
+ preprocessed_info.source = preprocessed;
|
|
+ ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data);
|
|
+
|
|
+ vkd3d_shader_free_shader_code(&preprocessed);
|
|
+ }
|
|
+ break;
|
|
+
|
|
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
|
|
ret = d3dbc_parse(compile_info, config_flags, message_context, program);
|
|
break;
|
|
@@ -803,13 +852,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp
|
|
|
|
if (TRACE_ON())
|
|
vsir_program_trace(program);
|
|
-
|
|
- vsir_program_cleanup(program);
|
|
- return ret;
|
|
+ goto fail;
|
|
}
|
|
|
|
- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE)
|
|
- ret = vsir_program_transform_early(program, config_flags, compile_info, message_context);
|
|
+ if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE
|
|
+ && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0)
|
|
+ goto fail;
|
|
+
|
|
+ return ret;
|
|
+
|
|
+fail:
|
|
+ vkd3d_shader_free_shader_code(reflection_data);
|
|
+ vsir_program_cleanup(program);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -1233,6 +1288,40 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
|
|
s->sampler_index = sampler_idx;
|
|
}
|
|
|
|
+static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context,
|
|
+ const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
|
|
+{
|
|
+ unsigned int resource_idx = resource->idx[0].offset;
|
|
+ unsigned int sampler_idx = sampler->idx[0].offset;
|
|
+
|
|
+ vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler);
|
|
+
|
|
+ if (!context->scan_descriptor_info)
|
|
+ return;
|
|
+
|
|
+ /* Sample instructions lowered from 1.x texture instructions have no
|
|
+ * DCL, so we need to add the resource if it didn't already exist.
|
|
+ * Such descriptors have a fixed count, type, etc. */
|
|
+
|
|
+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
|
|
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx))
|
|
+ {
|
|
+ struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx};
|
|
+
|
|
+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource,
|
|
+ &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32);
|
|
+ }
|
|
+
|
|
+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
|
|
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx))
|
|
+ {
|
|
+ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
|
|
+
|
|
+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource,
|
|
+ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED);
|
|
+ }
|
|
+}
|
|
+
|
|
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
|
|
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
|
|
enum vsir_data_type resource_data_type, unsigned int sample_count,
|
|
@@ -1436,13 +1525,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
|
|
if (context->cf_info_count)
|
|
context->cf_info[context->cf_info_count - 1].inside_block = false;
|
|
break;
|
|
- case VSIR_OP_TEXLD:
|
|
- if (context->version->major == 1)
|
|
- sampler_reg = &instruction->dst[0].reg;
|
|
- else
|
|
- sampler_reg = &instruction->src[1].reg;
|
|
- vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg);
|
|
- break;
|
|
case VSIR_OP_TEX:
|
|
case VSIR_OP_TEXBEM:
|
|
case VSIR_OP_TEXBEML:
|
|
@@ -1459,7 +1541,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
|
|
break;
|
|
case VSIR_OP_GATHER4:
|
|
case VSIR_OP_GATHER4_C:
|
|
- case VSIR_OP_SAMPLE:
|
|
case VSIR_OP_SAMPLE_B:
|
|
case VSIR_OP_SAMPLE_C:
|
|
case VSIR_OP_SAMPLE_C_LZ:
|
|
@@ -1467,6 +1548,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
|
|
case VSIR_OP_SAMPLE_LOD:
|
|
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg);
|
|
break;
|
|
+ case VSIR_OP_SAMPLE:
|
|
+ vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg);
|
|
+ break;
|
|
case VSIR_OP_GATHER4_PO:
|
|
case VSIR_OP_GATHER4_PO_C:
|
|
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg);
|
|
@@ -1691,7 +1775,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
|
|
int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
|
|
{
|
|
struct vkd3d_shader_message_context message_context;
|
|
+ struct vkd3d_shader_code reflection_data = {0};
|
|
struct shader_dump_data dump_data;
|
|
+ struct vsir_program program;
|
|
int ret;
|
|
|
|
TRACE("compile_info %p, messages %p.\n", compile_info, messages);
|
|
@@ -1709,21 +1795,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
|
|
fill_shader_dump_data(compile_info, &dump_data);
|
|
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
|
|
|
|
- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
|
|
- {
|
|
- FIXME("HLSL support not implemented.\n");
|
|
- ret = VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
- }
|
|
- else
|
|
+ if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(),
|
|
+ &dump_data, &message_context, &program, &reflection_data)))
|
|
{
|
|
- uint64_t config_flags = vkd3d_shader_init_config_flags();
|
|
- struct vsir_program program;
|
|
-
|
|
- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program)))
|
|
- {
|
|
- ret = vsir_program_scan(&program, compile_info, &message_context, false);
|
|
- vsir_program_cleanup(&program);
|
|
- }
|
|
+ ret = vsir_program_scan(&program, compile_info, &message_context, false);
|
|
+ vkd3d_shader_free_shader_code(&reflection_data);
|
|
+ vsir_program_cleanup(&program);
|
|
}
|
|
|
|
vkd3d_shader_message_context_trace_messages(&message_context);
|
|
@@ -1733,12 +1810,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
|
|
return ret;
|
|
}
|
|
|
|
-int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data,
|
|
+static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data,
|
|
uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info,
|
|
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info;
|
|
struct vkd3d_shader_compile_info scan_info;
|
|
+ enum vsir_asm_flags asm_flags;
|
|
int ret;
|
|
|
|
scan_info = *compile_info;
|
|
@@ -1748,7 +1826,11 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader
|
|
case VKD3D_SHADER_TARGET_D3D_ASM:
|
|
if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0)
|
|
return ret;
|
|
- ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE);
|
|
+ asm_flags = VSIR_ASM_FLAG_NONE;
|
|
+ if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF
|
|
+ && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE)
|
|
+ asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS;
|
|
+ ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context);
|
|
break;
|
|
|
|
case VKD3D_SHADER_TARGET_D3D_BYTECODE:
|
|
@@ -1795,7 +1877,7 @@ int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader
|
|
return ret;
|
|
}
|
|
|
|
-static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
|
|
+static int fx_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|
const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out,
|
|
struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
@@ -1810,10 +1892,7 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
preprocessed_info = *compile_info;
|
|
preprocessed_info.source = preprocessed;
|
|
- if (compile_info->target_type == VKD3D_SHADER_TARGET_FX)
|
|
- ret = hlsl_compile_effect(&preprocessed_info, message_context, out);
|
|
- else
|
|
- ret = hlsl_compile_shader(&preprocessed_info, message_context, out);
|
|
+ ret = hlsl_compile_effect(&preprocessed_info, message_context, out);
|
|
|
|
vkd3d_shader_free_shader_code(&preprocessed);
|
|
return ret;
|
|
@@ -1841,9 +1920,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|
fill_shader_dump_data(compile_info, &dump_data);
|
|
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
|
|
|
|
- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
|
|
+ if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL
|
|
+ && compile_info->target_type == VKD3D_SHADER_TARGET_FX)
|
|
{
|
|
- ret = compile_hlsl(compile_info, &dump_data, out, &message_context);
|
|
+ ret = fx_compile(compile_info, &dump_data, out, &message_context);
|
|
}
|
|
else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX)
|
|
{
|
|
@@ -1856,11 +1936,14 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
|
|
else
|
|
{
|
|
uint64_t config_flags = vkd3d_shader_init_config_flags();
|
|
+ struct vkd3d_shader_code reflection_data = {0};
|
|
struct vsir_program program;
|
|
|
|
- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program)))
|
|
+ if (!(ret = vsir_parse(compile_info, config_flags, &dump_data,
|
|
+ &message_context, &program, &reflection_data)))
|
|
{
|
|
- ret = vsir_program_compile(&program, NULL, config_flags, compile_info, out, &message_context);
|
|
+ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context);
|
|
+ vkd3d_shader_free_shader_code(&reflection_data);
|
|
vsir_program_cleanup(&program);
|
|
}
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index 5bf3728a325..e758c16b3d4 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -937,6 +937,16 @@ enum vkd3d_shader_type
|
|
|
|
struct vkd3d_shader_message_context;
|
|
|
|
+struct vkd3d_shader_source_list
|
|
+{
|
|
+ const char **sources;
|
|
+ size_t capacity, count;
|
|
+};
|
|
+
|
|
+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source);
|
|
+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l);
|
|
+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l);
|
|
+
|
|
struct vkd3d_shader_version
|
|
{
|
|
enum vkd3d_shader_type type;
|
|
@@ -1013,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe
|
|
}
|
|
}
|
|
|
|
+static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input(
|
|
+ enum vkd3d_shader_sysval_semantic sysval)
|
|
+{
|
|
+ switch (sysval)
|
|
+ {
|
|
+ case VKD3D_SHADER_SV_PRIMITIVE_ID:
|
|
+ return VKD3DSPR_PRIMID;
|
|
+ case VKD3D_SHADER_SV_COVERAGE:
|
|
+ return VKD3DSPR_COVERAGE;
|
|
+ default:
|
|
+ return VKD3DSPR_INPUT;
|
|
+ }
|
|
+}
|
|
+
|
|
struct vkd3d_shader_dst_param
|
|
{
|
|
struct vkd3d_shader_register reg;
|
|
@@ -1463,12 +1487,21 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct
|
|
static inline struct vkd3d_shader_instruction *vsir_program_iterator_next(
|
|
struct vsir_program_iterator *iterator)
|
|
{
|
|
- if (iterator->idx < iterator->array->count)
|
|
+ if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX)
|
|
++iterator->idx;
|
|
|
|
return vsir_program_iterator_current(iterator);
|
|
}
|
|
|
|
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev(
|
|
+ struct vsir_program_iterator *iterator)
|
|
+{
|
|
+ if (iterator->idx != SIZE_MAX)
|
|
+ --iterator->idx;
|
|
+
|
|
+ return vsir_program_iterator_current(iterator);
|
|
+}
|
|
+
|
|
/* When insertion takes place, argument `it' is updated to point to the same
|
|
* instruction as before the insertion, but all other iterators and pointers
|
|
* to the same container are invalidated and cannot be used any more. */
|
|
@@ -1563,6 +1596,7 @@ struct vsir_program
|
|
|
|
struct vsir_features features;
|
|
|
|
+ struct vkd3d_shader_source_list source_files;
|
|
const char **block_names;
|
|
size_t block_name_count;
|
|
};
|
|
@@ -1572,14 +1606,13 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
|
|
enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
|
|
struct vkd3d_shader_message_context *message_context);
|
|
void vsir_program_cleanup(struct vsir_program *program);
|
|
-int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data,
|
|
- uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
|
|
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 vsir_control_flow_type cf_type,
|
|
enum vsir_normalisation_level normalisation_level);
|
|
+enum vkd3d_result vsir_program_lower_d3dbc(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_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_transform_early(struct vsir_program *program, uint64_t config_flags,
|
|
@@ -1652,11 +1685,12 @@ enum vsir_asm_flags
|
|
VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2,
|
|
VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4,
|
|
VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8,
|
|
+ VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10,
|
|
};
|
|
|
|
enum vkd3d_result d3d_asm_compile(struct vsir_program *program,
|
|
- const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_code *out, enum vsir_asm_flags flags);
|
|
+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
|
|
+ enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context);
|
|
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
|
|
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
|
|
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
|
|
@@ -1808,8 +1842,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info,
|
|
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out);
|
|
-int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out);
|
|
+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
|
|
+ struct vkd3d_shader_message_context *message_context,
|
|
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data);
|
|
|
|
static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type)
|
|
{
|
|
--
|
|
2.50.1
|
|
|