mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
1719 lines
71 KiB
Diff
1719 lines
71 KiB
Diff
From 1652829e1c0845b53db7cc789c6ea1043beb4f55 Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Wed, 9 Oct 2024 20:40:25 +1100
|
|
Subject: [PATCH] Updated vkd3d to cd74461d6dabae4e702de61a90533d811aa0a3fb.
|
|
|
|
---
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 59 ++-
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 2 +-
|
|
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 2 -
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 10 +-
|
|
libs/vkd3d/libs/vkd3d-shader/glsl.c | 254 ++++++++++---
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 1 -
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 103 ++---
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 9 +-
|
|
libs/vkd3d/libs/vkd3d-shader/msl.c | 357 +++++++++++++++++-
|
|
libs/vkd3d/libs/vkd3d-shader/preproc.h | 3 +-
|
|
libs/vkd3d/libs/vkd3d-shader/preproc.l | 53 +--
|
|
libs/vkd3d/libs/vkd3d-shader/preproc.y | 13 -
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 17 +-
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 7 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 2 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 10 +-
|
|
16 files changed, 726 insertions(+), 176 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
index 9fe4b74486a..38d566d9fe0 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -2268,7 +2268,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic
|
|
}
|
|
}
|
|
|
|
-static enum vkd3d_result dump_signature(struct vkd3d_d3d_asm_compiler *compiler,
|
|
+static enum vkd3d_result dump_dxbc_signature(struct vkd3d_d3d_asm_compiler *compiler,
|
|
const char *name, const char *register_name, const struct shader_signature *signature)
|
|
{
|
|
struct vkd3d_string_buffer *buffer = &compiler->buffer;
|
|
@@ -2335,21 +2335,21 @@ static enum vkd3d_result dump_signature(struct vkd3d_d3d_asm_compiler *compiler,
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
-static enum vkd3d_result dump_signatures(struct vkd3d_d3d_asm_compiler *compiler,
|
|
+static enum vkd3d_result dump_dxbc_signatures(struct vkd3d_d3d_asm_compiler *compiler,
|
|
const struct vsir_program *program)
|
|
{
|
|
enum vkd3d_result ret;
|
|
|
|
- if ((ret = dump_signature(compiler, ".input",
|
|
+ if ((ret = dump_dxbc_signature(compiler, ".input",
|
|
program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN ? "vicp" : "v",
|
|
&program->input_signature)) < 0)
|
|
return ret;
|
|
|
|
- if ((ret = dump_signature(compiler, ".output", "o",
|
|
+ if ((ret = dump_dxbc_signature(compiler, ".output", "o",
|
|
&program->output_signature)) < 0)
|
|
return ret;
|
|
|
|
- if ((ret = dump_signature(compiler, ".patch_constant",
|
|
+ if ((ret = dump_dxbc_signature(compiler, ".patch_constant",
|
|
program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN ? "vpc" : "o",
|
|
&program->patch_constant_signature)) < 0)
|
|
return ret;
|
|
@@ -2437,7 +2437,7 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
|
|
* doesn't even have an explicit concept of signature. */
|
|
if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4)
|
|
{
|
|
- if ((result = dump_signatures(&compiler, program)) < 0)
|
|
+ if ((result = dump_dxbc_signatures(&compiler, program)) < 0)
|
|
{
|
|
vkd3d_string_buffer_cleanup(buffer);
|
|
return result;
|
|
@@ -2499,12 +2499,57 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
|
|
return result;
|
|
}
|
|
|
|
-void vkd3d_shader_trace(const struct vsir_program *program)
|
|
+/* This is meant exclusively for development use. Therefore, differently from
|
|
+ * dump_dxbc_signature(), it doesn't try particularly hard to make the output
|
|
+ * nice or easily parsable, and it dumps all fields, not just the DXBC ones.
|
|
+ * This format isn't meant to be stable. */
|
|
+static void trace_signature(const struct shader_signature *signature, const char *signature_type)
|
|
+{
|
|
+ struct vkd3d_string_buffer buffer;
|
|
+ unsigned int i;
|
|
+
|
|
+ TRACE("%s signature:%s\n", signature_type, signature->element_count == 0 ? " empty" : "");
|
|
+
|
|
+ vkd3d_string_buffer_init(&buffer);
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ const struct signature_element *element = &signature->elements[i];
|
|
+
|
|
+ vkd3d_string_buffer_clear(&buffer);
|
|
+
|
|
+ vkd3d_string_buffer_printf(&buffer, "Element %u: %s %u-%u %s", i,
|
|
+ get_component_type_name(element->component_type),
|
|
+ element->register_index, element->register_index + element->register_count,
|
|
+ element->semantic_name);
|
|
+ if (element->semantic_index != -1)
|
|
+ vkd3d_string_buffer_printf(&buffer, "%u", element->semantic_index);
|
|
+ vkd3d_string_buffer_printf(&buffer,
|
|
+ " mask %#x used_mask %#x sysval %s min_precision %s interpolation %u stream %u",
|
|
+ element->mask, element->used_mask, get_sysval_semantic_name(element->sysval_semantic),
|
|
+ get_minimum_precision_name(element->min_precision), element->interpolation_mode,
|
|
+ element->stream_index);
|
|
+ if (element->target_location != -1)
|
|
+ vkd3d_string_buffer_printf(&buffer, " target %u", element->target_location);
|
|
+ else
|
|
+ vkd3d_string_buffer_printf(&buffer, " unused");
|
|
+
|
|
+ TRACE("%s\n", buffer.buffer);
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_cleanup(&buffer);
|
|
+}
|
|
+
|
|
+void vsir_program_trace(const struct vsir_program *program)
|
|
{
|
|
const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES;
|
|
struct vkd3d_shader_code code;
|
|
const char *p, *q, *end;
|
|
|
|
+ trace_signature(&program->input_signature, "Input");
|
|
+ trace_signature(&program->output_signature, "Output");
|
|
+ trace_signature(&program->patch_constant_signature, "Patch-constant");
|
|
+
|
|
if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK)
|
|
return;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 267cf410cbe..589b800f8c9 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -1390,7 +1390,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
|
|
WARN("Failed to validate shader after parsing, ret %d.\n", ret);
|
|
|
|
if (TRACE_ON())
|
|
- vkd3d_shader_trace(program);
|
|
+ vsir_program_trace(program);
|
|
|
|
vsir_program_cleanup(program);
|
|
return ret;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
index 93fc993e0d1..f6ac8e0829e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
@@ -419,8 +419,6 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
|
|
const char *name;
|
|
uint32_t mask;
|
|
|
|
- e[i].sort_index = i;
|
|
-
|
|
if (has_stream_index)
|
|
e[i].stream_index = read_u32(&ptr);
|
|
else
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index d4296ef4bc5..c66b059325a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -4174,6 +4174,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
|
|
const struct sm6_type *type_b, struct sm6_parser *sm6)
|
|
{
|
|
bool is_int = sm6_type_is_bool_i16_i32_i64(type_a);
|
|
+ bool is_double = sm6_type_is_double(type_a);
|
|
bool is_bool = sm6_type_is_bool(type_a);
|
|
enum vkd3d_shader_opcode op;
|
|
bool is_valid;
|
|
@@ -4198,7 +4199,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
|
|
case BINOP_ADD:
|
|
case BINOP_SUB:
|
|
/* NEG is applied later for subtraction. */
|
|
- op = is_int ? VKD3DSIH_IADD : VKD3DSIH_ADD;
|
|
+ op = is_int ? VKD3DSIH_IADD : (is_double ? VKD3DSIH_DADD : VKD3DSIH_ADD);
|
|
is_valid = !is_bool;
|
|
break;
|
|
case BINOP_AND:
|
|
@@ -4214,7 +4215,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
|
|
is_valid = is_int && !is_bool;
|
|
break;
|
|
case BINOP_MUL:
|
|
- op = is_int ? VKD3DSIH_UMUL : VKD3DSIH_MUL;
|
|
+ op = is_int ? VKD3DSIH_UMUL : (is_double ? VKD3DSIH_DMUL : VKD3DSIH_MUL);
|
|
is_valid = !is_bool;
|
|
break;
|
|
case BINOP_OR:
|
|
@@ -4222,7 +4223,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
|
|
is_valid = is_int;
|
|
break;
|
|
case BINOP_SDIV:
|
|
- op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_DIV;
|
|
+ op = is_int ? VKD3DSIH_IDIV : (is_double ? VKD3DSIH_DDIV : VKD3DSIH_DIV);
|
|
is_valid = !is_bool;
|
|
break;
|
|
case BINOP_SREM:
|
|
@@ -9637,6 +9638,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co
|
|
ins->declaration.thread_group_size.x = group_sizes[0];
|
|
ins->declaration.thread_group_size.y = group_sizes[1];
|
|
ins->declaration.thread_group_size.z = group_sizes[2];
|
|
+ sm6->p.program->thread_group_size = ins->declaration.thread_group_size;
|
|
|
|
return VKD3D_OK;
|
|
}
|
|
@@ -10592,7 +10594,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co
|
|
WARN("Failed to validate shader after parsing, ret %d.\n", ret);
|
|
|
|
if (TRACE_ON())
|
|
- vkd3d_shader_trace(program);
|
|
+ vsir_program_trace(program);
|
|
|
|
sm6_parser_cleanup(&sm6);
|
|
vsir_program_cleanup(program);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
index c2fb58c55e6..4dc95899a11 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
@@ -62,6 +62,9 @@ struct vkd3d_glsl_generator
|
|
const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info;
|
|
};
|
|
|
|
+static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
|
|
+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset);
|
|
+
|
|
static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error(
|
|
struct vkd3d_glsl_generator *generator,
|
|
enum vkd3d_shader_error error, const char *fmt, ...)
|
|
@@ -263,6 +266,11 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
|
|
gen->prefix, reg->idx[0].offset, reg->idx[2].offset);
|
|
break;
|
|
|
|
+ case VKD3DSPR_IDXTEMP:
|
|
+ vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset);
|
|
+ shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset);
|
|
+ break;
|
|
+
|
|
default:
|
|
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
"Internal compiler error: Unhandled register type %#x.", reg->type);
|
|
@@ -438,6 +446,26 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener
|
|
return write_mask;
|
|
}
|
|
|
|
+static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
|
|
+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset)
|
|
+{
|
|
+ struct glsl_src r;
|
|
+
|
|
+ if (!rel_addr)
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(buffer, "[%u]", offset);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ glsl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0);
|
|
+ vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer);
|
|
+ if (offset)
|
|
+ vkd3d_string_buffer_printf(buffer, " + %u", offset);
|
|
+ else
|
|
+ vkd3d_string_buffer_printf(buffer, "]");
|
|
+ glsl_src_cleanup(&r, &gen->string_buffers);
|
|
+}
|
|
+
|
|
static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen,
|
|
struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args)
|
|
{
|
|
@@ -903,19 +931,27 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st
|
|
switch (sysval)
|
|
{
|
|
case VKD3D_SHADER_SV_POSITION:
|
|
- if (version->type == VKD3D_SHADER_TYPE_PIXEL || version->type == VKD3D_SHADER_TYPE_COMPUTE)
|
|
+ if (version->type == VKD3D_SHADER_TYPE_COMPUTE)
|
|
{
|
|
vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>", sysval);
|
|
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled system value %#x.", sysval);
|
|
+ "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", version->type);
|
|
+ break;
|
|
}
|
|
+ if (idx)
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled SV_POSITION index %u.", idx);
|
|
+ if (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
|
+ vkd3d_string_buffer_printf(buffer, "gl_FragCoord");
|
|
else
|
|
- {
|
|
vkd3d_string_buffer_printf(buffer, "gl_Position");
|
|
- if (idx)
|
|
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled SV_POSITION index %u.", idx);
|
|
- }
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_SV_VERTEX_ID:
|
|
+ if (version->type != VKD3D_SHADER_TYPE_VERTEX)
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", version->type);
|
|
+ vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))");
|
|
break;
|
|
|
|
case VKD3D_SHADER_SV_IS_FRONT_FACE:
|
|
@@ -972,7 +1008,19 @@ static void shader_glsl_shader_prologue(struct vkd3d_glsl_generator *gen)
|
|
}
|
|
else
|
|
{
|
|
- vkd3d_string_buffer_printf(buffer, " = shader_in_%u", i);
|
|
+ switch (e->component_type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, " = uintBitsToFloat(shader_in_%u)", i);
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled input component type %#x.", e->component_type);
|
|
+ /* fall through */
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, " = shader_in_%u", i);
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
else
|
|
@@ -989,6 +1037,7 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen)
|
|
{
|
|
const struct shader_signature *signature = &gen->program->output_signature;
|
|
struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ enum vkd3d_shader_component_type type;
|
|
const struct signature_element *e;
|
|
unsigned int i;
|
|
|
|
@@ -999,11 +1048,13 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen)
|
|
if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
continue;
|
|
|
|
+ type = e->component_type;
|
|
shader_glsl_print_indent(buffer, gen->indent);
|
|
if (e->sysval_semantic == VKD3D_SHADER_SV_NONE)
|
|
{
|
|
if (gen->interstage_output)
|
|
{
|
|
+ type = VKD3D_SHADER_COMPONENT_FLOAT;
|
|
vkd3d_string_buffer_printf(buffer, "shader_out.reg_%u", e->target_location);
|
|
if (e->target_location >= gen->limits.output_count)
|
|
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
@@ -1023,7 +1074,19 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen)
|
|
shader_glsl_print_sysval_name(buffer, gen, e->sysval_semantic, e->semantic_index);
|
|
}
|
|
shader_glsl_print_write_mask(buffer, e->mask);
|
|
- vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index);
|
|
+ switch (type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, " = floatBitsToUint(%s_out[%u])", gen->prefix, e->register_index);
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled output component type %#x.", e->component_type);
|
|
+ /* fall through */
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index);
|
|
+ break;
|
|
+ }
|
|
shader_glsl_print_write_mask(buffer, e->mask);
|
|
vkd3d_string_buffer_printf(buffer, ";\n");
|
|
}
|
|
@@ -1041,6 +1104,15 @@ static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d
|
|
}
|
|
}
|
|
|
|
+static void shader_glsl_dcl_indexable_temp(struct vkd3d_glsl_generator *gen,
|
|
+ const struct vkd3d_shader_instruction *ins)
|
|
+{
|
|
+ shader_glsl_print_indent(gen->buffer, gen->indent);
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "vec4 x%u[%u];\n",
|
|
+ ins->declaration.indexable_temp.register_idx,
|
|
+ ins->declaration.indexable_temp.register_size);
|
|
+}
|
|
+
|
|
static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
|
|
const struct vkd3d_shader_instruction *ins)
|
|
{
|
|
@@ -1049,14 +1121,19 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
|
|
switch (ins->opcode)
|
|
{
|
|
case VKD3DSIH_ADD:
|
|
+ case VKD3DSIH_IADD:
|
|
shader_glsl_binop(gen, ins, "+");
|
|
break;
|
|
case VKD3DSIH_AND:
|
|
shader_glsl_binop(gen, ins, "&");
|
|
break;
|
|
+ case VKD3DSIH_DCL_INDEXABLE_TEMP:
|
|
+ shader_glsl_dcl_indexable_temp(gen, ins);
|
|
+ break;
|
|
case VKD3DSIH_DCL_INPUT:
|
|
case VKD3DSIH_DCL_INPUT_PS:
|
|
case VKD3DSIH_DCL_INPUT_PS_SIV:
|
|
+ case VKD3DSIH_DCL_INPUT_SGV:
|
|
case VKD3DSIH_DCL_OUTPUT:
|
|
case VKD3DSIH_DCL_OUTPUT_SIV:
|
|
case VKD3DSIH_NOP:
|
|
@@ -1079,6 +1156,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
|
|
case VKD3DSIH_ENDIF:
|
|
shader_glsl_endif(gen);
|
|
break;
|
|
+ case VKD3DSIH_EQO:
|
|
case VKD3DSIH_IEQ:
|
|
shader_glsl_relop(gen, ins, "==", "equal");
|
|
break;
|
|
@@ -1108,26 +1186,30 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
|
|
case VKD3DSIH_LTO:
|
|
shader_glsl_relop(gen, ins, "<", "lessThan");
|
|
break;
|
|
- case VKD3DSIH_IMUL:
|
|
- shader_glsl_mul_extended(gen, ins);
|
|
- break;
|
|
- case VKD3DSIH_ISHL:
|
|
- shader_glsl_binop(gen, ins, "<<");
|
|
- break;
|
|
- case VKD3DSIH_ISHR:
|
|
- case VKD3DSIH_USHR:
|
|
- shader_glsl_binop(gen, ins, ">>");
|
|
- break;
|
|
+ case VKD3DSIH_IMAX:
|
|
case VKD3DSIH_MAX:
|
|
shader_glsl_intrinsic(gen, ins, "max");
|
|
break;
|
|
case VKD3DSIH_MIN:
|
|
shader_glsl_intrinsic(gen, ins, "min");
|
|
break;
|
|
+ case VKD3DSIH_IMUL:
|
|
+ shader_glsl_mul_extended(gen, ins);
|
|
+ break;
|
|
case VKD3DSIH_INE:
|
|
case VKD3DSIH_NEU:
|
|
shader_glsl_relop(gen, ins, "!=", "notEqual");
|
|
break;
|
|
+ case VKD3DSIH_INEG:
|
|
+ shader_glsl_unary_op(gen, ins, "-");
|
|
+ break;
|
|
+ case VKD3DSIH_ISHL:
|
|
+ shader_glsl_binop(gen, ins, "<<");
|
|
+ break;
|
|
+ case VKD3DSIH_ISHR:
|
|
+ case VKD3DSIH_USHR:
|
|
+ shader_glsl_binop(gen, ins, ">>");
|
|
+ break;
|
|
case VKD3DSIH_ITOF:
|
|
case VKD3DSIH_UTOF:
|
|
shader_glsl_cast(gen, ins, "float", "vec");
|
|
@@ -1485,15 +1567,62 @@ static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_gener
|
|
vkd3d_string_buffer_printf(gen->buffer, "\n");
|
|
}
|
|
|
|
-static void shader_glsl_generate_interface_block(struct vkd3d_string_buffer *buffer,
|
|
- const char *type, unsigned int count)
|
|
+static const struct signature_element *signature_get_element_by_location(
|
|
+ const struct shader_signature *signature, unsigned int location)
|
|
{
|
|
+ const struct signature_element *e;
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ e = &signature->elements[i];
|
|
+
|
|
+ if (e->target_location != location)
|
|
+ continue;
|
|
+
|
|
+ return e;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static const char *shader_glsl_get_interpolation(struct vkd3d_glsl_generator *gen,
|
|
+ const struct shader_signature *signature, const char *type, unsigned int location)
|
|
+{
|
|
+ enum vkd3d_shader_interpolation_mode m;
|
|
+ const struct signature_element *e;
|
|
+
|
|
+ if ((e = signature_get_element_by_location(signature, location)))
|
|
+ m = e->interpolation_mode;
|
|
+ else
|
|
+ m = VKD3DSIM_NONE;
|
|
+
|
|
+ switch (m)
|
|
+ {
|
|
+ case VKD3DSIM_NONE:
|
|
+ case VKD3DSIM_LINEAR:
|
|
+ return "";
|
|
+ case VKD3DSIM_CONSTANT:
|
|
+ return "flat ";
|
|
+ default:
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled interpolation mode %#x for %s location %u.", m, type, location);
|
|
+ return "";
|
|
+ }
|
|
+}
|
|
+
|
|
+static void shader_glsl_generate_interface_block(struct vkd3d_glsl_generator *gen,
|
|
+ const struct shader_signature *signature, const char *type, unsigned int count)
|
|
+{
|
|
+ struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ const char *interpolation;
|
|
unsigned int i;
|
|
|
|
vkd3d_string_buffer_printf(buffer, "%s shader_in_out\n{\n", type);
|
|
for (i = 0; i < count; ++i)
|
|
{
|
|
- vkd3d_string_buffer_printf(buffer, " vec4 reg_%u;\n", i);
|
|
+ interpolation = shader_glsl_get_interpolation(gen, signature, type, i);
|
|
+ vkd3d_string_buffer_printf(buffer, " %svec4 reg_%u;\n", interpolation, i);
|
|
}
|
|
vkd3d_string_buffer_printf(buffer, "} shader_%s;\n", type);
|
|
}
|
|
@@ -1503,30 +1632,16 @@ static void shader_glsl_generate_input_declarations(struct vkd3d_glsl_generator
|
|
const struct shader_signature *signature = &gen->program->input_signature;
|
|
struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
const struct signature_element *e;
|
|
- unsigned int i;
|
|
+ unsigned int i, count;
|
|
|
|
if (!gen->interstage_input)
|
|
{
|
|
- for (i = 0; i < signature->element_count; ++i)
|
|
+ for (i = 0, count = 0; i < signature->element_count; ++i)
|
|
{
|
|
e = &signature->elements[i];
|
|
|
|
- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
- continue;
|
|
-
|
|
- if (e->sysval_semantic)
|
|
- {
|
|
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic);
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (e->component_type != VKD3D_SHADER_COMPONENT_FLOAT)
|
|
- {
|
|
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled component type %#x.", e->component_type);
|
|
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED || e->sysval_semantic)
|
|
continue;
|
|
- }
|
|
|
|
if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
|
|
{
|
|
@@ -1542,15 +1657,32 @@ static void shader_glsl_generate_input_declarations(struct vkd3d_glsl_generator
|
|
continue;
|
|
}
|
|
|
|
- vkd3d_string_buffer_printf(buffer,
|
|
- "layout(location = %u) in vec4 shader_in_%u;\n", e->target_location, i);
|
|
+ vkd3d_string_buffer_printf(buffer, "layout(location = %u) in ", e->target_location);
|
|
+ switch (e->component_type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, "uvec4");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, "vec4");
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_string_buffer_printf(buffer, "<unhandled type %#x>", e->component_type);
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled input component type %#x.", e->component_type);
|
|
+ break;
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(buffer, " shader_in_%u;\n", i);
|
|
+ ++count;
|
|
}
|
|
+ if (count)
|
|
+ vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
else if (gen->limits.input_count)
|
|
{
|
|
- shader_glsl_generate_interface_block(buffer, "in", gen->limits.input_count);
|
|
+ shader_glsl_generate_interface_block(gen, signature, "in", gen->limits.input_count);
|
|
+ vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
- vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
|
|
static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator *gen)
|
|
@@ -1558,11 +1690,11 @@ static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator
|
|
const struct shader_signature *signature = &gen->program->output_signature;
|
|
struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
const struct signature_element *e;
|
|
- unsigned int i;
|
|
+ unsigned int i, count;
|
|
|
|
if (!gen->interstage_output)
|
|
{
|
|
- for (i = 0; i < signature->element_count; ++i)
|
|
+ for (i = 0, count = 0; i < signature->element_count; ++i)
|
|
{
|
|
e = &signature->elements[i];
|
|
|
|
@@ -1576,13 +1708,6 @@ static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator
|
|
continue;
|
|
}
|
|
|
|
- if (e->component_type != VKD3D_SHADER_COMPONENT_FLOAT)
|
|
- {
|
|
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled component type %#x.", e->component_type);
|
|
- continue;
|
|
- }
|
|
-
|
|
if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
|
|
{
|
|
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
@@ -1597,15 +1722,32 @@ static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator
|
|
continue;
|
|
}
|
|
|
|
- vkd3d_string_buffer_printf(buffer,
|
|
- "layout(location = %u) out vec4 shader_out_%u;\n", e->target_location, i);
|
|
+ vkd3d_string_buffer_printf(buffer, "layout(location = %u) out ", e->target_location);
|
|
+ switch (e->component_type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, "uvec4");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, "vec4");
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_string_buffer_printf(buffer, "<unhandled type %#x>", e->component_type);
|
|
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled output component type %#x.", e->component_type);
|
|
+ break;
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(buffer, " shader_out_%u;\n", i);
|
|
+ ++count;
|
|
}
|
|
+ if (count)
|
|
+ vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
else if (gen->limits.output_count)
|
|
{
|
|
- shader_glsl_generate_interface_block(buffer, "out", gen->limits.output_count);
|
|
+ shader_glsl_generate_interface_block(gen, signature, "out", gen->limits.output_count);
|
|
+ vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
- vkd3d_string_buffer_printf(buffer, "\n");
|
|
}
|
|
|
|
static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index 9ace1930c1b..b44c0296f69 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -1621,7 +1621,6 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp
|
|
{
|
|
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2};
|
|
|
|
- VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
|
|
return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc);
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index ef37eb75f03..2230cd5b919 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -461,6 +461,40 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
|
|
return add_cast(ctx, block, node, dst_type, loc);
|
|
}
|
|
|
|
+static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
+ struct hlsl_type *dst_type, const struct parse_array_sizes *arrays, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ struct hlsl_ir_node *instr = node_from_block(block);
|
|
+ struct hlsl_type *src_type = instr->data_type;
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < arrays->count; ++i)
|
|
+ {
|
|
+ if (arrays->sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT)
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Implicit size arrays not allowed in casts.");
|
|
+ dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i]);
|
|
+ }
|
|
+
|
|
+ if (instr->data_type->class == HLSL_CLASS_ERROR)
|
|
+ return true;
|
|
+
|
|
+ if (!explicit_compatible_data_types(ctx, src_type, dst_type))
|
|
+ {
|
|
+ struct vkd3d_string_buffer *src_string, *dst_string;
|
|
+
|
|
+ src_string = hlsl_type_to_string(ctx, src_type);
|
|
+ dst_string = hlsl_type_to_string(ctx, dst_type);
|
|
+ if (src_string && dst_string)
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.",
|
|
+ src_string->buffer, dst_string->buffer);
|
|
+ hlsl_release_string_buffer(ctx, src_string);
|
|
+ hlsl_release_string_buffer(ctx, dst_string);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return add_cast(ctx, block, instr, dst_type, loc);
|
|
+}
|
|
+
|
|
static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t mod,
|
|
const struct vkd3d_shader_location *loc)
|
|
{
|
|
@@ -978,6 +1012,12 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str
|
|
const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type;
|
|
struct hlsl_ir_node *return_index, *cast;
|
|
|
|
+ if (array->data_type->class == HLSL_CLASS_ERROR || index->data_type->class == HLSL_CLASS_ERROR)
|
|
+ {
|
|
+ block->value = ctx->error_instr;
|
|
+ return true;
|
|
+ }
|
|
+
|
|
if ((expr_type->class == HLSL_CLASS_TEXTURE || expr_type->class == HLSL_CLASS_UAV)
|
|
&& expr_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
|
|
{
|
|
@@ -2314,6 +2354,9 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d
|
|
struct hlsl_ir_node *lhs = node_from_block(block);
|
|
struct hlsl_ir_node *one;
|
|
|
|
+ if (lhs->data_type->class == HLSL_CLASS_ERROR)
|
|
+ return true;
|
|
+
|
|
if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST)
|
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST,
|
|
"Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in");
|
|
@@ -2366,9 +2409,9 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
|
|
{
|
|
struct hlsl_default_value default_value = {0};
|
|
|
|
- if (hlsl_is_numeric_type(dst_comp_type))
|
|
+ if (src->type == HLSL_IR_COMPILE || src->type == HLSL_IR_SAMPLER_STATE)
|
|
{
|
|
- if (src->type == HLSL_IR_COMPILE || src->type == HLSL_IR_SAMPLER_STATE)
|
|
+ if (hlsl_is_numeric_type(dst_comp_type))
|
|
{
|
|
/* Default values are discarded if they contain an object
|
|
* literal expression for a numeric component. */
|
|
@@ -2381,17 +2424,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
|
|
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);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if (!hlsl_clone_block(ctx, &block, instrs))
|
|
+ return;
|
|
+ default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
|
|
|
|
- if (dst->default_values)
|
|
- dst->default_values[*store_index] = default_value;
|
|
+ if (dst->default_values)
|
|
+ dst->default_values[*store_index] = default_value;
|
|
|
|
- hlsl_block_cleanup(&block);
|
|
- }
|
|
+ hlsl_block_cleanup(&block);
|
|
}
|
|
}
|
|
else
|
|
@@ -8770,7 +8813,6 @@ postfix_expr:
|
|
YYABORT;
|
|
}
|
|
vkd3d_free($3);
|
|
- $$ = $1;
|
|
}
|
|
else if (hlsl_is_numeric_type(node->data_type))
|
|
{
|
|
@@ -8784,14 +8826,14 @@ postfix_expr:
|
|
}
|
|
hlsl_block_add_instr($1, swizzle);
|
|
vkd3d_free($3);
|
|
- $$ = $1;
|
|
}
|
|
- else
|
|
+ else if (node->data_type->class != HLSL_CLASS_ERROR)
|
|
{
|
|
hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3);
|
|
vkd3d_free($3);
|
|
YYABORT;
|
|
}
|
|
+ $$ = $1;
|
|
}
|
|
| postfix_expr '[' expr ']'
|
|
{
|
|
@@ -8903,10 +8945,6 @@ unary_expr:
|
|
/* var_modifiers is necessary to avoid shift/reduce conflicts. */
|
|
| '(' var_modifiers type arrays ')' unary_expr
|
|
{
|
|
- struct hlsl_type *src_type = node_from_block($6)->data_type;
|
|
- struct hlsl_type *dst_type;
|
|
- unsigned int i;
|
|
-
|
|
if ($2)
|
|
{
|
|
hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
@@ -8914,36 +8952,13 @@ unary_expr:
|
|
YYABORT;
|
|
}
|
|
|
|
- dst_type = $3;
|
|
- for (i = 0; i < $4.count; ++i)
|
|
- {
|
|
- if ($4.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT)
|
|
- {
|
|
- hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
- "Implicit size arrays not allowed in casts.");
|
|
- }
|
|
- dst_type = hlsl_new_array_type(ctx, dst_type, $4.sizes[i]);
|
|
- }
|
|
-
|
|
- if (!explicit_compatible_data_types(ctx, src_type, dst_type))
|
|
- {
|
|
- struct vkd3d_string_buffer *src_string, *dst_string;
|
|
-
|
|
- src_string = hlsl_type_to_string(ctx, src_type);
|
|
- dst_string = hlsl_type_to_string(ctx, dst_type);
|
|
- if (src_string && dst_string)
|
|
- hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.",
|
|
- src_string->buffer, dst_string->buffer);
|
|
- hlsl_release_string_buffer(ctx, src_string);
|
|
- hlsl_release_string_buffer(ctx, dst_string);
|
|
- YYABORT;
|
|
- }
|
|
-
|
|
- if (!add_cast(ctx, $6, node_from_block($6), dst_type, &@3))
|
|
+ if (!add_explicit_conversion(ctx, $6, $3, &$4, &@3))
|
|
{
|
|
destroy_block($6);
|
|
+ vkd3d_free($4.sizes);
|
|
YYABORT;
|
|
}
|
|
+ vkd3d_free($4.sizes);
|
|
$$ = $6;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 6a74e2eb8de..14cf23e8d1a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -681,6 +681,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
|
case VKD3DSIH_DCL_CONSTANT_BUFFER:
|
|
case VKD3DSIH_DCL_SAMPLER:
|
|
case VKD3DSIH_DCL_TEMPS:
|
|
+ case VKD3DSIH_DCL_THREAD_GROUP:
|
|
vkd3d_shader_instruction_make_nop(ins);
|
|
break;
|
|
|
|
@@ -763,7 +764,7 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i
|
|
}
|
|
|
|
for (i = 0; i < ins->dst_count; ++i)
|
|
- shader_register_eliminate_phase_addressing((struct vkd3d_shader_register *)&ins->dst[i].reg, instance_id);
|
|
+ shader_register_eliminate_phase_addressing(&ins->dst[i].reg, instance_id);
|
|
}
|
|
|
|
static const struct vkd3d_shader_varying_map *find_varying_map(
|
|
@@ -1470,6 +1471,9 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map
|
|
return false;
|
|
memcpy(elements, s->elements, element_count * sizeof(*elements));
|
|
|
|
+ for (i = 0; i < element_count; ++i)
|
|
+ elements[i].sort_index = i;
|
|
+
|
|
qsort(elements, element_count, sizeof(elements[0]), signature_element_register_compare);
|
|
|
|
for (i = 0, new_count = 0; i < element_count; i = j, elements[new_count++] = *e)
|
|
@@ -1667,7 +1671,6 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
|
|
vkd3d_unreachable();
|
|
e = &signature->elements[element_idx];
|
|
|
|
- dst_param->write_mask >>= vsir_write_mask_get_component_idx(e->mask);
|
|
if (is_io_dcl)
|
|
{
|
|
/* Validated in the TPF reader. */
|
|
@@ -7149,7 +7152,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
|
|
vsir_transform(&ctx, vsir_program_insert_clip_planes);
|
|
|
|
if (TRACE_ON())
|
|
- vkd3d_shader_trace(program);
|
|
+ vsir_program_trace(program);
|
|
|
|
return ctx.result;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
index 6b41363d60e..bfc013959e7 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
@@ -38,6 +38,7 @@ struct msl_generator
|
|
struct vkd3d_shader_location location;
|
|
struct vkd3d_shader_message_context *message_context;
|
|
unsigned int indent;
|
|
+ const char *prefix;
|
|
};
|
|
|
|
static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen,
|
|
@@ -50,16 +51,37 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen
|
|
va_end(args);
|
|
}
|
|
|
|
+static const char *msl_get_prefix(enum vkd3d_shader_type type)
|
|
+{
|
|
+ switch (type)
|
|
+ {
|
|
+ case VKD3D_SHADER_TYPE_VERTEX:
|
|
+ return "vs";
|
|
+ case VKD3D_SHADER_TYPE_HULL:
|
|
+ return "hs";
|
|
+ case VKD3D_SHADER_TYPE_DOMAIN:
|
|
+ return "ds";
|
|
+ case VKD3D_SHADER_TYPE_GEOMETRY:
|
|
+ return "gs";
|
|
+ case VKD3D_SHADER_TYPE_PIXEL:
|
|
+ return "ps";
|
|
+ case VKD3D_SHADER_TYPE_COMPUTE:
|
|
+ return "cs";
|
|
+ default:
|
|
+ return NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent)
|
|
{
|
|
vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, "");
|
|
}
|
|
|
|
static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer,
|
|
- struct msl_generator *gen, const struct vkd3d_shader_register *reg)
|
|
+ struct msl_generator *gen, enum vkd3d_data_type data_type)
|
|
{
|
|
vkd3d_string_buffer_printf(buffer, ".");
|
|
- switch (reg->data_type)
|
|
+ switch (data_type)
|
|
{
|
|
case VKD3D_DATA_FLOAT:
|
|
vkd3d_string_buffer_printf(buffer, "f");
|
|
@@ -72,8 +94,8 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer,
|
|
break;
|
|
default:
|
|
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
- "Internal compiler error: Unhandled register datatype %#x.", reg->data_type);
|
|
- vkd3d_string_buffer_printf(buffer, "<unrecognised register datatype %#x>", reg->data_type);
|
|
+ "Internal compiler error: Unhandled register datatype %#x.", data_type);
|
|
+ vkd3d_string_buffer_printf(buffer, "<unrecognised register datatype %#x>", data_type);
|
|
break;
|
|
}
|
|
}
|
|
@@ -85,7 +107,7 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer,
|
|
{
|
|
case VKD3DSPR_TEMP:
|
|
vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset);
|
|
- msl_print_register_datatype(buffer, gen, reg);
|
|
+ msl_print_register_datatype(buffer, gen, reg->data_type);
|
|
break;
|
|
default:
|
|
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
@@ -244,6 +266,309 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
|
}
|
|
}
|
|
|
|
+static void msl_generate_input_struct_declarations(struct msl_generator *gen)
|
|
+{
|
|
+ const struct shader_signature *signature = &gen->program->input_signature;
|
|
+ enum vkd3d_shader_type type = gen->program->shader_version.type;
|
|
+ struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ const struct signature_element *e;
|
|
+ unsigned int i;
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_in\n{\n", gen->prefix);
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ e = &signature->elements[i];
|
|
+
|
|
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
+ continue;
|
|
+
|
|
+ if (e->sysval_semantic)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (e->interpolation_mode != VKD3DSIM_NONE)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if(e->register_count > 1)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled register count %u.", e->register_count);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ msl_print_indent(gen->buffer, 1);
|
|
+
|
|
+ switch(e->component_type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, "float4 ");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_INT:
|
|
+ vkd3d_string_buffer_printf(buffer, "int4 ");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, "uint4 ");
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_string_buffer_printf(buffer, "<unhandled component type %#x> ", e->component_type);
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled component type %#x.", e->component_type);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i);
|
|
+
|
|
+ switch (type)
|
|
+ {
|
|
+ case VKD3D_SHADER_TYPE_VERTEX:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location);
|
|
+ break;
|
|
+ case VKD3D_SHADER_TYPE_PIXEL:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location);
|
|
+ break;
|
|
+ default:
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled shader type %#x.", type);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, ";\n");
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "};\n\n");
|
|
+}
|
|
+
|
|
+static void msl_generate_vertex_output_element_attribute(struct msl_generator *gen, const struct signature_element *e)
|
|
+{
|
|
+ switch (e->sysval_semantic)
|
|
+ {
|
|
+ case VKD3D_SHADER_SV_POSITION:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "[[position]]");
|
|
+ break;
|
|
+ case VKD3D_SHADER_SV_NONE:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location);
|
|
+ break;
|
|
+ default:
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled vertex shader system value %#x.", e->sysval_semantic);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void msl_generate_pixel_output_element_attribute(struct msl_generator *gen, const struct signature_element *e)
|
|
+{
|
|
+ switch (e->sysval_semantic)
|
|
+ {
|
|
+ case VKD3D_SHADER_SV_TARGET:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "[[color(%u)]]", e->target_location);
|
|
+ break;
|
|
+ default:
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled pixel shader system value %#x.", e->sysval_semantic);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void msl_generate_output_struct_declarations(struct msl_generator *gen)
|
|
+{
|
|
+ const struct shader_signature *signature = &gen->program->output_signature;
|
|
+ enum vkd3d_shader_type type = gen->program->shader_version.type;
|
|
+ struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ const struct signature_element *e;
|
|
+ unsigned int i;
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_out\n{\n", gen->prefix);
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ e = &signature->elements[i];
|
|
+
|
|
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
+ continue;
|
|
+
|
|
+ if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (e->interpolation_mode != VKD3DSIM_NONE)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if(e->register_count > 1)
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled register count %u.", e->register_count);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ msl_print_indent(gen->buffer, 1);
|
|
+
|
|
+ switch(e->component_type)
|
|
+ {
|
|
+ case VKD3D_SHADER_COMPONENT_FLOAT:
|
|
+ vkd3d_string_buffer_printf(buffer, "float4 ");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_INT:
|
|
+ vkd3d_string_buffer_printf(buffer, "int4 ");
|
|
+ break;
|
|
+ case VKD3D_SHADER_COMPONENT_UINT:
|
|
+ vkd3d_string_buffer_printf(buffer, "uint4 ");
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_string_buffer_printf(buffer, "<unhandled component type %#x> ", e->component_type);
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled component type %#x.", e->component_type);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "shader_out_%u ", i);
|
|
+
|
|
+ switch (type)
|
|
+ {
|
|
+ case VKD3D_SHADER_TYPE_VERTEX:
|
|
+ msl_generate_vertex_output_element_attribute(gen, e);
|
|
+ break;
|
|
+ case VKD3D_SHADER_TYPE_PIXEL:
|
|
+ msl_generate_pixel_output_element_attribute(gen, e);
|
|
+ break;
|
|
+ default:
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled shader type %#x.", type);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, ";\n");
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "};\n\n");
|
|
+}
|
|
+
|
|
+static void msl_generate_entrypoint_prologue(struct msl_generator *gen)
|
|
+{
|
|
+ const struct shader_signature *signature = &gen->program->input_signature;
|
|
+ struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ const struct signature_element *e;
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ e = &signature->elements[i];
|
|
+
|
|
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
+ continue;
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index);
|
|
+ if (e->sysval_semantic == VKD3D_SHADER_SV_NONE)
|
|
+ {
|
|
+ msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type));
|
|
+ msl_print_write_mask(buffer, e->mask);
|
|
+ vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i);
|
|
+ msl_print_write_mask(buffer, e->mask);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic);
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(buffer, ";\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void msl_generate_entrypoint_epilogue(struct msl_generator *gen)
|
|
+{
|
|
+ const struct shader_signature *signature = &gen->program->output_signature;
|
|
+ struct vkd3d_string_buffer *buffer = gen->buffer;
|
|
+ const struct signature_element *e;
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ e = &signature->elements[i];
|
|
+
|
|
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
+ continue;
|
|
+
|
|
+ switch (e->sysval_semantic)
|
|
+ {
|
|
+ case VKD3D_SHADER_SV_NONE:
|
|
+ case VKD3D_SHADER_SV_TARGET:
|
|
+ case VKD3D_SHADER_SV_POSITION:
|
|
+ vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i);
|
|
+ msl_print_write_mask(buffer, e->mask);
|
|
+ vkd3d_string_buffer_printf(buffer, " = %s_out", gen->prefix);
|
|
+ msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type));
|
|
+ msl_print_write_mask(buffer, e->mask);
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_string_buffer_printf(buffer, " <unhandled sysval %#x>", e->sysval_semantic);
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(buffer, ";\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void msl_generate_entrypoint(struct msl_generator *gen)
|
|
+{
|
|
+ enum vkd3d_shader_type type = gen->program->shader_version.type;
|
|
+
|
|
+ switch (type)
|
|
+ {
|
|
+ case VKD3D_SHADER_TYPE_VERTEX:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "vertex ");
|
|
+ break;
|
|
+ case VKD3D_SHADER_TYPE_PIXEL:
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "fragment ");
|
|
+ break;
|
|
+ default:
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled shader type %#x.", type);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix);
|
|
+
|
|
+ /* TODO: descriptor declaration */
|
|
+
|
|
+ msl_print_indent(gen->buffer, 1);
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix);
|
|
+
|
|
+ /* TODO: declare #maximum_register + 1 */
|
|
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32);
|
|
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32);
|
|
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix);
|
|
+
|
|
+ msl_generate_entrypoint_prologue(gen);
|
|
+
|
|
+ vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out);\n", gen->prefix, gen->prefix, gen->prefix);
|
|
+
|
|
+ msl_generate_entrypoint_epilogue(gen);
|
|
+
|
|
+ vkd3d_string_buffer_printf(gen->buffer, " return output;\n}\n");
|
|
+}
|
|
+
|
|
static void msl_generator_generate(struct msl_generator *gen)
|
|
{
|
|
const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions;
|
|
@@ -258,7 +583,13 @@ static void msl_generator_generate(struct msl_generator *gen)
|
|
vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n");
|
|
vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n");
|
|
|
|
- vkd3d_string_buffer_printf(gen->buffer, "void shader_main()\n{\n");
|
|
+ msl_generate_input_struct_declarations(gen);
|
|
+ msl_generate_output_struct_declarations(gen);
|
|
+
|
|
+ vkd3d_string_buffer_printf(gen->buffer,
|
|
+ "void %s_main(thread vkd3d_vec4 *v, "
|
|
+ "thread vkd3d_vec4 *o)\n{\n",
|
|
+ gen->prefix);
|
|
|
|
++gen->indent;
|
|
|
|
@@ -273,7 +604,11 @@ static void msl_generator_generate(struct msl_generator *gen)
|
|
msl_handle_instruction(gen, &instructions->elements[i]);
|
|
}
|
|
|
|
- vkd3d_string_buffer_printf(gen->buffer, "}\n");
|
|
+ --gen->indent;
|
|
+
|
|
+ vkd3d_string_buffer_printf(gen->buffer, "}\n\n");
|
|
+
|
|
+ msl_generate_entrypoint(gen);
|
|
|
|
if (TRACE_ON())
|
|
vkd3d_string_buffer_trace(gen->buffer);
|
|
@@ -288,6 +623,8 @@ static void msl_generator_cleanup(struct msl_generator *gen)
|
|
static int msl_generator_init(struct msl_generator *gen, struct vsir_program *program,
|
|
struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
+ enum vkd3d_shader_type type = program->shader_version.type;
|
|
+
|
|
memset(gen, 0, sizeof(*gen));
|
|
gen->program = program;
|
|
vkd3d_string_buffer_cache_init(&gen->string_buffers);
|
|
@@ -297,6 +634,12 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
gen->message_context = message_context;
|
|
+ if (!(gen->prefix = msl_get_prefix(type)))
|
|
+ {
|
|
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
|
|
+ "Internal compiler error: Unhandled shader type %#x.", type);
|
|
+ return VKD3D_ERROR_INVALID_SHADER;
|
|
+ }
|
|
|
|
return VKD3D_OK;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
index 9806614a35b..a98c8ae3df5 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h
|
|
@@ -60,6 +60,7 @@ struct preproc_expansion
|
|
{
|
|
struct preproc_buffer buffer;
|
|
const struct preproc_text *text;
|
|
+ struct preproc_text *arg_values;
|
|
/* Back-pointer to the macro, if this expansion a macro body. This is
|
|
* necessary so that argument tokens can be correctly replaced. */
|
|
struct preproc_macro *macro;
|
|
@@ -72,7 +73,6 @@ struct preproc_macro
|
|
|
|
char **arg_names;
|
|
size_t arg_count;
|
|
- struct preproc_text *arg_values;
|
|
|
|
struct preproc_text body;
|
|
};
|
|
@@ -117,6 +117,7 @@ struct preproc_ctx
|
|
STATE_ARGS,
|
|
} state;
|
|
unsigned int paren_depth;
|
|
+ struct preproc_text *arg_values;
|
|
} text_func, directive_func;
|
|
|
|
int current_directive;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
index 41c21cca1f5..d167415c356 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
@@ -30,11 +30,11 @@
|
|
|
|
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
|
|
|
|
-static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx)
|
|
+static struct preproc_expansion *preproc_get_top_expansion(struct preproc_ctx *ctx)
|
|
{
|
|
if (!ctx->expansion_count)
|
|
return NULL;
|
|
- return ctx->expansion_stack[ctx->expansion_count - 1].macro;
|
|
+ return &ctx->expansion_stack[ctx->expansion_count - 1];
|
|
}
|
|
|
|
static void update_location(struct preproc_ctx *ctx);
|
|
@@ -133,14 +133,14 @@ INT_SUFFIX [uUlL]{0,2}
|
|
|
|
if (!ctx->last_was_newline)
|
|
{
|
|
- struct preproc_macro *macro;
|
|
+ struct preproc_expansion *exp;
|
|
|
|
/* Stringification is only done for function-like macro bodies.
|
|
* Anywhere else, we need to parse it as two separate tokens.
|
|
* We could use a state for this, but yyless() is easier and cheap.
|
|
*/
|
|
|
|
- if ((macro = preproc_get_top_macro(ctx)) && macro->arg_count)
|
|
+ if ((exp = preproc_get_top_expansion(ctx)) && exp->macro && exp->macro->arg_count)
|
|
return T_HASHSTRING;
|
|
|
|
yyless(1);
|
|
@@ -259,6 +259,12 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx)
|
|
|
|
yy_delete_buffer(exp->buffer.lexer_buffer, ctx->scanner);
|
|
|
|
+ if (exp->macro)
|
|
+ {
|
|
+ for (unsigned int i = 0; i < exp->macro->arg_count; ++i)
|
|
+ vkd3d_string_buffer_cleanup(&exp->arg_values[i].text);
|
|
+ free(exp->arg_values);
|
|
+ }
|
|
--ctx->expansion_count;
|
|
TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count);
|
|
}
|
|
@@ -311,15 +317,15 @@ static int return_token(int token, YYSTYPE *lval, const char *text)
|
|
|
|
static const struct preproc_text *find_arg_expansion(struct preproc_ctx *ctx, const char *s)
|
|
{
|
|
- struct preproc_macro *macro;
|
|
+ struct preproc_expansion *exp;
|
|
unsigned int i;
|
|
|
|
- if ((macro = preproc_get_top_macro(ctx)))
|
|
+ if ((exp = preproc_get_top_expansion(ctx)) && exp->macro)
|
|
{
|
|
- for (i = 0; i < macro->arg_count; ++i)
|
|
+ for (i = 0; i < exp->macro->arg_count; ++i)
|
|
{
|
|
- if (!strcmp(s, macro->arg_names[i]))
|
|
- return ¯o->arg_values[i];
|
|
+ if (!strcmp(s, exp->macro->arg_names[i]))
|
|
+ return &exp->arg_values[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
@@ -331,7 +337,7 @@ static void preproc_text_add(struct preproc_text *text, const char *string)
|
|
}
|
|
|
|
static bool preproc_push_expansion(struct preproc_ctx *ctx,
|
|
- const struct preproc_text *text, struct preproc_macro *macro)
|
|
+ const struct preproc_text *text, struct preproc_macro *macro, struct preproc_text *arg_values)
|
|
{
|
|
struct preproc_expansion *exp;
|
|
|
|
@@ -343,6 +349,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx,
|
|
exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner);
|
|
exp->buffer.location = text->location;
|
|
exp->macro = macro;
|
|
+ exp->arg_values = arg_values;
|
|
TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count);
|
|
return true;
|
|
}
|
|
@@ -543,7 +550,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
|
|
if ((expansion = find_arg_expansion(ctx, text)))
|
|
{
|
|
- preproc_push_expansion(ctx, expansion, NULL);
|
|
+ preproc_push_expansion(ctx, expansion, NULL, NULL);
|
|
continue;
|
|
}
|
|
|
|
@@ -551,7 +558,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
{
|
|
if (!macro->arg_count)
|
|
{
|
|
- preproc_push_expansion(ctx, ¯o->body, macro);
|
|
+ preproc_push_expansion(ctx, ¯o->body, macro, NULL);
|
|
}
|
|
else
|
|
{
|
|
@@ -617,16 +624,19 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
case STATE_IDENTIFIER:
|
|
if (token == '(')
|
|
{
|
|
- struct preproc_text *first_arg = &func_state->macro->arg_values[0];
|
|
- unsigned int i;
|
|
+ struct preproc_text *arg_values;
|
|
+
|
|
+ if (!(arg_values = calloc(func_state->macro->arg_count, sizeof(*arg_values))))
|
|
+ return 0;
|
|
+
|
|
+ for (unsigned int i = 0; i < func_state->macro->arg_count; ++i)
|
|
+ vkd3d_string_buffer_init(&arg_values[i].text);
|
|
+ arg_values[0].location = *lloc;
|
|
|
|
func_state->arg_count = 0;
|
|
func_state->paren_depth = 1;
|
|
func_state->state = STATE_ARGS;
|
|
- for (i = 0; i < func_state->macro->arg_count; ++i)
|
|
- func_state->macro->arg_values[i].text.content_size = 0;
|
|
-
|
|
- first_arg->location = *lloc;
|
|
+ func_state->arg_values = arg_values;
|
|
}
|
|
else
|
|
{
|
|
@@ -650,7 +660,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
VKD3D_ASSERT(func_state->macro->arg_count);
|
|
|
|
if (func_state->arg_count < func_state->macro->arg_count)
|
|
- current_arg = &func_state->macro->arg_values[func_state->arg_count];
|
|
+ current_arg = &func_state->arg_values[func_state->arg_count];
|
|
|
|
switch (token)
|
|
{
|
|
@@ -665,7 +675,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
|
|
if ((expansion = find_arg_expansion(ctx, text)))
|
|
{
|
|
- preproc_push_expansion(ctx, expansion, NULL);
|
|
+ preproc_push_expansion(ctx, expansion, NULL, NULL);
|
|
continue;
|
|
}
|
|
|
|
@@ -701,7 +711,8 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
{
|
|
if (++func_state->arg_count == func_state->macro->arg_count)
|
|
{
|
|
- preproc_push_expansion(ctx, &func_state->macro->body, func_state->macro);
|
|
+ preproc_push_expansion(ctx, &func_state->macro->body,
|
|
+ func_state->macro, func_state->arg_values);
|
|
}
|
|
else
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.y b/libs/vkd3d/libs/vkd3d-shader/preproc.y
|
|
index 366e351e3b5..c6be17bd230 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.y
|
|
@@ -91,7 +91,6 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati
|
|
size_t arg_count, const struct vkd3d_shader_location *body_loc, struct vkd3d_string_buffer *body)
|
|
{
|
|
struct preproc_macro *macro;
|
|
- unsigned int i;
|
|
int ret;
|
|
|
|
if ((macro = preproc_find_macro(ctx, name)))
|
|
@@ -108,14 +107,6 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati
|
|
macro->name = name;
|
|
macro->arg_names = arg_names;
|
|
macro->arg_count = arg_count;
|
|
- macro->arg_values = NULL;
|
|
- if (arg_count && !(macro->arg_values = vkd3d_calloc(arg_count, sizeof(*macro->arg_values))))
|
|
- {
|
|
- vkd3d_free(macro);
|
|
- return false;
|
|
- }
|
|
- for (i = 0; i < arg_count; ++i)
|
|
- vkd3d_string_buffer_init(¯o->arg_values[i].text);
|
|
macro->body.text = *body;
|
|
macro->body.location = *body_loc;
|
|
ret = rb_put(&ctx->macros, name, ¯o->entry);
|
|
@@ -129,12 +120,8 @@ void preproc_free_macro(struct preproc_macro *macro)
|
|
|
|
vkd3d_free(macro->name);
|
|
for (i = 0; i < macro->arg_count; ++i)
|
|
- {
|
|
- vkd3d_string_buffer_cleanup(¯o->arg_values[i].text);
|
|
vkd3d_free(macro->arg_names[i]);
|
|
- }
|
|
vkd3d_free(macro->arg_names);
|
|
- vkd3d_free(macro->arg_values);
|
|
vkd3d_string_buffer_cleanup(¯o->body.text);
|
|
vkd3d_free(macro);
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 11c054a28f5..cb610c929b6 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -5510,7 +5510,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
|
|
const struct shader_signature *shader_signature;
|
|
const struct vkd3d_spirv_builtin *builtin;
|
|
enum vkd3d_shader_sysval_semantic sysval;
|
|
- uint32_t write_mask, reg_write_mask;
|
|
+ uint32_t write_mask;
|
|
bool use_private_variable = false;
|
|
struct vkd3d_symbol reg_symbol;
|
|
SpvStorageClass storage_class;
|
|
@@ -5561,7 +5561,6 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
|
|
use_private_variable = true;
|
|
}
|
|
|
|
- reg_write_mask = write_mask >> component_idx;
|
|
vkd3d_symbol_make_io(®_symbol, reg_type, element_idx);
|
|
|
|
if (rb_get(&compiler->symbol_table, ®_symbol))
|
|
@@ -5639,7 +5638,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
|
|
|
|
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
|
|
use_private_variable ? VKD3D_SHADER_COMPONENT_FLOAT : component_type,
|
|
- use_private_variable ? VKD3DSP_WRITEMASK_ALL : reg_write_mask);
|
|
+ use_private_variable ? VKD3DSP_WRITEMASK_ALL : write_mask);
|
|
reg_symbol.info.reg.is_aggregate = array_sizes[0] || array_sizes[1];
|
|
VKD3D_ASSERT(!builtin || !builtin->spirv_array_size || use_private_variable || array_sizes[0] || array_sizes[1]);
|
|
|
|
@@ -5650,7 +5649,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
|
|
if (use_private_variable)
|
|
{
|
|
compiler->private_output_variable[element_idx] = var_id;
|
|
- compiler->private_output_variable_write_mask[element_idx] |= reg_write_mask;
|
|
+ compiler->private_output_variable_write_mask[element_idx] |= write_mask >> component_idx;
|
|
if (!compiler->epilogue_function_id)
|
|
compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder);
|
|
}
|
|
@@ -6891,10 +6890,9 @@ static void spirv_compiler_emit_tessellator_partitioning(struct spirv_compiler *
|
|
spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0);
|
|
}
|
|
|
|
-static void spirv_compiler_emit_dcl_thread_group(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_instruction *instruction)
|
|
+static void spirv_compiler_emit_thread_group_size(struct spirv_compiler *compiler,
|
|
+ const struct vsir_thread_group_size *group_size)
|
|
{
|
|
- const struct vkd3d_shader_thread_group_size *group_size = &instruction->declaration.thread_group_size;
|
|
const uint32_t local_size[] = {group_size->x, group_size->y, group_size->z};
|
|
|
|
spirv_compiler_emit_execution_mode(compiler,
|
|
@@ -10228,9 +10226,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
spirv_compiler_emit_tessellator_partitioning(compiler,
|
|
instruction->declaration.tessellator_partitioning);
|
|
break;
|
|
- case VKD3DSIH_DCL_THREAD_GROUP:
|
|
- spirv_compiler_emit_dcl_thread_group(compiler, instruction);
|
|
- break;
|
|
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
|
|
case VKD3DSIH_HS_FORK_PHASE:
|
|
case VKD3DSIH_HS_JOIN_PHASE:
|
|
@@ -10650,6 +10645,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct
|
|
spirv_compiler_emit_temps(compiler, program->temp_count);
|
|
if (program->ssa_count)
|
|
spirv_compiler_allocate_ssa_register_ids(compiler, program->ssa_count);
|
|
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_COMPUTE)
|
|
+ spirv_compiler_emit_thread_group_size(compiler, &program->thread_group_size);
|
|
|
|
spirv_compiler_emit_descriptor_declarations(compiler);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 00a525c9ac3..75bdb06fe0e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -1289,11 +1289,14 @@ static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instructio
|
|
}
|
|
|
|
static void shader_sm5_read_dcl_thread_group(struct vkd3d_shader_instruction *ins, uint32_t opcode,
|
|
- uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
|
|
+ uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
|
|
{
|
|
+ struct vsir_program *program = sm4->p.program;
|
|
+
|
|
ins->declaration.thread_group_size.x = *tokens++;
|
|
ins->declaration.thread_group_size.y = *tokens++;
|
|
ins->declaration.thread_group_size.z = *tokens++;
|
|
+ program->thread_group_size = ins->declaration.thread_group_size;
|
|
}
|
|
|
|
static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
|
|
@@ -2959,7 +2962,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
|
|
WARN("Failed to validate shader after parsing, ret %d.\n", ret);
|
|
|
|
if (TRACE_ON())
|
|
- vkd3d_shader_trace(program);
|
|
+ vsir_program_trace(program);
|
|
|
|
vsir_program_cleanup(program);
|
|
return ret;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index ee8a633431a..9b320106340 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -1489,7 +1489,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
|
|
descriptor_info1, combined_sampler_info, message_context);
|
|
|
|
if (TRACE_ON())
|
|
- vkd3d_shader_trace(program);
|
|
+ vsir_program_trace(program);
|
|
|
|
for (i = 0; i < program->instructions.count; ++i)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index eab164cc848..1a42f385fc0 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -1061,6 +1061,9 @@ enum vkd3d_shader_input_sysval_semantic
|
|
|
|
struct signature_element
|
|
{
|
|
+ /* sort_index is not a property of the signature element, it is just a
|
|
+ * convenience field used to retain the original order in a signature and
|
|
+ * recover it after having permuted the signature itself. */
|
|
unsigned int sort_index;
|
|
const char *semantic_name;
|
|
unsigned int semantic_index;
|
|
@@ -1164,7 +1167,7 @@ struct vkd3d_shader_tgsm_structured
|
|
bool zero_init;
|
|
};
|
|
|
|
-struct vkd3d_shader_thread_group_size
|
|
+struct vsir_thread_group_size
|
|
{
|
|
unsigned int x, y, z;
|
|
};
|
|
@@ -1243,7 +1246,7 @@ struct vkd3d_shader_instruction
|
|
struct vkd3d_shader_structured_resource structured_resource;
|
|
struct vkd3d_shader_tgsm_raw tgsm_raw;
|
|
struct vkd3d_shader_tgsm_structured tgsm_structured;
|
|
- struct vkd3d_shader_thread_group_size thread_group_size;
|
|
+ struct vsir_thread_group_size thread_group_size;
|
|
enum vkd3d_tessellator_domain tessellator_domain;
|
|
enum vkd3d_shader_tessellator_output_primitive tessellator_output_primitive;
|
|
enum vkd3d_shader_tessellator_partitioning tessellator_partitioning;
|
|
@@ -1390,6 +1393,7 @@ struct vsir_program
|
|
bool free_parameters;
|
|
|
|
unsigned int input_control_point_count, output_control_point_count;
|
|
+ struct vsir_thread_group_size thread_group_size;
|
|
unsigned int flat_constant_count[3];
|
|
unsigned int block_count;
|
|
unsigned int temp_count;
|
|
@@ -1474,7 +1478,7 @@ struct vkd3d_shader_scan_descriptor_info1
|
|
unsigned int descriptor_count;
|
|
};
|
|
|
|
-void vkd3d_shader_trace(const struct vsir_program *program);
|
|
+void vsir_program_trace(const struct vsir_program *program);
|
|
|
|
const char *shader_get_type_prefix(enum vkd3d_shader_type type);
|
|
|
|
--
|
|
2.45.2
|
|
|