Files
wine-staging/patches/vkd3d-latest/0003-Updated-vkd3d-to-e418bbcfac74230dfbf0c49b72c4f059cb1.patch

832 lines
31 KiB
Diff
Raw Normal View History

2025-04-05 11:52:49 +11:00
From 6d98fd430eead31dfd3e0c71e883d5225b0e1876 Mon Sep 17 00:00:00 2001
2025-03-22 15:33:02 +11:00
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 18 Mar 2025 08:53:16 +1100
Subject: [PATCH] Updated vkd3d to e418bbcfac74230dfbf0c49b72c4f059cb1afc00.
---
libs/vkd3d/libs/vkd3d-shader/fx.c | 415 ++++++++++++++----
libs/vkd3d/libs/vkd3d-shader/glsl.c | 3 +
libs/vkd3d/libs/vkd3d-shader/ir.c | 29 ++
libs/vkd3d/libs/vkd3d-shader/spirv.c | 41 +-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 54 +++
.../libs/vkd3d-shader/vkd3d_shader_private.h | 1 +
6 files changed, 423 insertions(+), 120 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index 4fbce393707..914c365b8f6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -25,6 +25,14 @@ static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uin
return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value));
}
+enum fx_2_type_constants
+{
+ /* Assignment types */
+ FX_2_ASSIGNMENT_CODE_BLOB = 0x0,
+ FX_2_ASSIGNMENT_PARAMETER = 0x1,
+ FX_2_ASSIGNMENT_ARRAY_SELECTOR = 0x2,
+};
+
enum state_property_component_type
{
FX_BOOL,
@@ -281,6 +289,15 @@ static void set_status(struct fx_write_context *fx, int status)
fx->status = status;
}
+static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix,
+ const char *s, size_t len)
+{
+ if (len)
+ --len; /* Trim terminating null. */
+ vkd3d_string_buffer_printf(buffer, "%s", prefix);
+ vkd3d_string_buffer_print_string_escaped(buffer, s, len);
+}
+
static uint32_t write_string(const char *string, struct fx_write_context *fx)
{
return fx->ops->write_string(string, fx);
@@ -725,6 +742,28 @@ static const struct rhs_named_value fx_2_lighttype_values[] =
{ NULL }
};
+static const struct rhs_named_value fx_2_address_values[] =
+{
+ { "WRAP", 1 },
+ { "MIRROR", 2 },
+ { "CLAMP", 3 },
+ { "BORDER", 4 },
+ { "MIRROR_ONCE", 5 },
+ { NULL }
+};
+
+static const struct rhs_named_value fx_2_filter_values[] =
+{
+ { "NONE", 0 },
+ { "POINT", 1 },
+ { "LINEAR", 2 },
+ { "ANISOTROPIC", 3 },
+ { "PYRAMIDALQUAD", 6 },
+ { "GAUSSIANQUAD", 7 },
+ { "CONVOLUTIONMONO", 8 },
+ { NULL }
+};
+
static const struct fx_2_state
{
const char *name;
@@ -895,6 +934,38 @@ fx_2_states[] =
{ "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 },
{ "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 },
+
+ { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 },
+ { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 },
+ { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 },
+ { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 },
+ { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 },
+ { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 },
+ { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 },
+ { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 },
+
+ { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 },
+ { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 },
+ { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 },
+ { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 },
+ { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 },
+ { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 },
+ { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 },
+ { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 },
+
+ { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 },
+ { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values },
+ { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values },
+ { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values },
+ { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 },
+ { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values },
+ { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values },
+ { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values },
+ { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 },
+ { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 },
+ { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 },
+ { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 },
+ { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 },
};
static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
@@ -3452,13 +3523,12 @@ static void parse_fx_print_indent(struct fx_parser *parser)
vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, "");
}
-static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset)
+static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size)
{
const char *ptr;
- uint32_t size;
- fx_parser_read_unstructured(parser, &size, offset, sizeof(size));
- ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, size);
+ fx_parser_read_unstructured(parser, size, offset, sizeof(*size));
+ ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size);
if (!ptr)
{
@@ -3624,13 +3694,14 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset)
uint32_t element_count;
} var;
const char *name;
+ uint32_t size;
fx_parser_read_unstructured(parser, &var, offset, sizeof(var));
fx_parse_fx_2_type(parser, offset);
- name = fx_2_get_string(parser, var.name);
- vkd3d_string_buffer_printf(&parser->buffer, " %s", name);
+ name = fx_2_get_string(parser, var.name, &size);
+ fx_print_string(&parser->buffer, " ", name, size);
if (var.element_count)
vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count);
}
@@ -3644,6 +3715,40 @@ static bool is_fx_2_sampler(uint32_t type)
|| type == D3DXPT_SAMPLERCUBE;
}
+static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry);
+
+static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count,
+ uint32_t offset)
+{
+ struct fx_assignment entry;
+ uint32_t count;
+
+ element_count = max(element_count, 1);
+
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
+ for (uint32_t i = 0; i < element_count; ++i)
+ {
+ fx_parser_read_unstructured(parser, &count, offset, sizeof(count));
+ offset += sizeof(count);
+
+ parse_fx_start_indent(parser);
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "{\n");
+ parse_fx_start_indent(parser);
+ for (uint32_t j = 0; j < count; ++j, offset += sizeof(entry))
+ {
+ fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry));
+
+ parse_fx_print_indent(parser);
+ fx_parse_fx_2_assignment(parser, &entry);
+ }
+ parse_fx_end_indent(parser);
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "},\n");
+ parse_fx_end_indent(parser);
+ }
+}
+
static void fx_parse_fx_2_initial_value(struct fx_parser *parser, uint32_t param, uint32_t value)
{
struct fx_2_var
@@ -3672,8 +3777,7 @@ static void fx_parse_fx_2_initial_value(struct fx_parser *parser, uint32_t param
if (var.class == D3DXPC_OBJECT)
{
if (is_fx_2_sampler(var.type))
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED,
- "Parsing sampler initializers is not supported.");
+ parse_fx_2_sampler(parser, var.element_count, value);
else
parse_fx_2_object_value(parser, var.element_count, var.type, value);
}
@@ -3714,24 +3818,22 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count)
vkd3d_string_buffer_printf(&parser->buffer, ">");
}
-static void fx_parse_fx_2_assignment(struct fx_parser *parser)
+static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry)
{
const struct rhs_named_value *named_value = NULL;
const struct fx_2_state *state = NULL;
- struct fx_assignment entry;
- fx_parser_read_u32s(parser, &entry, sizeof(entry));
- if (entry.id <= ARRAY_SIZE(fx_2_states))
+ if (entry->id <= ARRAY_SIZE(fx_2_states))
{
- state = &fx_2_states[entry.id];
+ state = &fx_2_states[entry->id];
vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name);
if (state->array_size > 1)
- vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry.lhs_index);
+ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index);
}
else
{
- vkd3d_string_buffer_printf(&parser->buffer, "<unrecognized state %u>", entry.id);
+ vkd3d_string_buffer_printf(&parser->buffer, "<unrecognized state %u>", entry->id);
}
vkd3d_string_buffer_printf(&parser->buffer, " = ");
@@ -3740,7 +3842,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser)
const struct rhs_named_value *ptr = state->values;
uint32_t value;
- fx_parser_read_unstructured(parser, &value, entry.value, sizeof(value));
+ fx_parser_read_unstructured(parser, &value, entry->value, sizeof(value));
while (ptr->name)
{
@@ -3757,13 +3859,27 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser)
{
vkd3d_string_buffer_printf(&parser->buffer, "%s /* %u */", named_value->name, named_value->value);
}
- else if (state && (state->type == FX_UINT || state->type == FX_FLOAT))
+ else if (state)
{
- uint32_t offset = entry.type;
- unsigned int size;
+ if (state->type == FX_UINT || state->type == FX_FLOAT)
+ {
+ uint32_t offset = entry->type;
+ unsigned int size;
- size = fx_get_fx_2_type_size(parser, &offset);
- parse_fx_2_numeric_value(parser, entry.value, size, entry.type);
+ size = fx_get_fx_2_type_size(parser, &offset);
+ parse_fx_2_numeric_value(parser, entry->value, size, entry->type);
+ }
+ else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER)
+ {
+ uint32_t id;
+
+ fx_parser_read_unstructured(parser, &id, entry->value, sizeof(id));
+ vkd3d_string_buffer_printf(&parser->buffer, "<object id %u>", id);
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "<ignored>");
+ }
}
else
{
@@ -3787,16 +3903,17 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
uint32_t assignment_count;
} pass;
const char *name;
+ uint32_t size;
if (parser->failed)
return;
fx_parser_read_u32s(parser, &technique, sizeof(technique));
- name = fx_2_get_string(parser, technique.name);
+ name = fx_2_get_string(parser, technique.name, &size);
parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "technique %s", name);
+ fx_print_string(&parser->buffer, "technique ", name, size);
fx_parse_fx_2_annotations(parser, technique.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n");
@@ -3807,10 +3924,10 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
for (uint32_t i = 0; i < technique.pass_count; ++i)
{
fx_parser_read_u32s(parser, &pass, sizeof(pass));
- name = fx_2_get_string(parser, pass.name);
+ name = fx_2_get_string(parser, pass.name, &size);
parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "pass %s", name);
+ fx_print_string(&parser->buffer, "pass ", name, size);
fx_parse_fx_2_annotations(parser, pass.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n");
@@ -3820,8 +3937,11 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
parse_fx_start_indent(parser);
for (uint32_t j = 0; j < pass.assignment_count; ++j)
{
+ struct fx_assignment entry;
+
parse_fx_print_indent(parser);
- fx_parse_fx_2_assignment(parser);
+ fx_parser_read_u32s(parser, &entry, sizeof(entry));
+ fx_parse_fx_2_assignment(parser, &entry);
}
parse_fx_end_indent(parser);
@@ -3858,10 +3978,62 @@ static void fx_2_parse_parameters(struct fx_parser *parser, uint32_t count)
vkd3d_string_buffer_printf(&parser->buffer, "\n");
}
+static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_source_type source_type,
+ const void *data, uint32_t data_size)
+{
+ struct vkd3d_shader_compile_info info = { 0 };
+ struct vkd3d_shader_code output;
+ const char *p, *q, *end;
+ int ret;
+
+ static const struct vkd3d_shader_compile_option options[] =
+ {
+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_15},
+ };
+
+ info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
+ info.source.code = data;
+ info.source.size = data_size;
+ info.source_type = source_type;
+ info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
+ info.options = options;
+ info.option_count = ARRAY_SIZE(options);
+ info.log_level = VKD3D_SHADER_LOG_INFO;
+
+ if ((ret = vkd3d_shader_compile(&info, &output, NULL)) < 0)
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Failed to disassemble shader blob.");
+ return;
+ }
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "asm {\n");
+
+ parse_fx_start_indent(parser);
+
+ end = (const char *)output.code + output.size;
+ for (p = output.code; p < end; p = q)
+ {
+ if (!(q = memchr(p, '\n', end - p)))
+ q = end;
+ else
+ ++q;
+
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "%.*s", (int)(q - p), p);
+ }
+
+ parse_fx_end_indent(parser);
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "}");
+
+ vkd3d_shader_free_shader_code(&output);
+}
+
static void fx_parse_fx_2_data_blob(struct fx_parser *parser)
{
uint32_t id, size;
- const char *str;
+ const void *data;
id = fx_parser_read_u32(parser);
size = fx_parser_read_u32(parser);
@@ -3882,13 +4054,24 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser)
case D3DXPT_VERTEXSHADER:
vkd3d_string_buffer_printf(&parser->buffer, "%s object %u size %u bytes%s\n",
fx_2_types[type], id, size, size ? ":" : ",");
- if (size && type == D3DXPT_STRING)
+
+ if (size)
{
- parse_fx_start_indent(parser);
- parse_fx_print_indent(parser);
- str = fx_parser_get_ptr(parser, size);
- vkd3d_string_buffer_printf(&parser->buffer, "\"%.*s\"\n", size, str);
- parse_fx_end_indent(parser);
+ data = fx_parser_get_ptr(parser, size);
+
+ if (type == D3DXPT_STRING)
+ {
+ parse_fx_start_indent(parser);
+ parse_fx_print_indent(parser);
+ fx_print_string(&parser->buffer, "\"", (const char *)data, size);
+ vkd3d_string_buffer_printf(&parser->buffer, "\"");
+ parse_fx_end_indent(parser);
+ }
+ else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER)
+ {
+ fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, data, size);
+ }
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
}
break;
default:
@@ -3903,9 +4086,117 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser)
fx_parser_skip(parser, align(size, 4));
}
+static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t size)
+{
+ const uint32_t *data = blob;
+ unsigned int i, j, n;
+
+ size /= sizeof(*data);
+ i = 0;
+ while (i < size)
+ {
+ parse_fx_print_indent(parser);
+ n = min(size - i, 8);
+ for (j = 0; j < n; ++j)
+ vkd3d_string_buffer_printf(&parser->buffer, "0x%08x,", data[i + j]);
+ i += n;
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
+ }
+}
+
+static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size)
+{
+ const uint8_t *end = parser->ptr + size;
+ uint32_t name_size, blob_size = 0;
+ const void *blob = NULL;
+ const char *name;
+
+ name_size = fx_parser_read_u32(parser);
+ name = fx_parser_get_ptr(parser, name_size);
+ fx_parser_skip(parser, name_size);
+
+ if (!name || (uint8_t *)name >= end)
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Malformed name entry in the array selector.");
+
+ if (parser->ptr <= end)
+ {
+ blob_size = end - parser->ptr;
+ blob = fx_parser_get_ptr(parser, blob_size);
+ fx_parser_skip(parser, blob_size);
+ }
+ else
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Malformed blob entry in the array selector.");
+ }
+
+ if (name)
+ {
+ fx_print_string(&parser->buffer, "array \"", name, name_size);
+ vkd3d_string_buffer_printf(&parser->buffer, "\"\n");
+ }
+ if (blob)
+ {
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size);
+ fx_dump_blob(parser, blob, blob_size);
+ }
+}
+
+static void fx_parse_fx_2_complex_state(struct fx_parser *parser)
+{
+ struct
+ {
+ uint32_t technique;
+ uint32_t index;
+ uint32_t element;
+ uint32_t state;
+ uint32_t assignment_type;
+ } state;
+ const char *data;
+ uint32_t size;
+
+ fx_parser_read_u32s(parser, &state, sizeof(state));
+
+ if (state.technique == ~0u)
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "parameter %u[%u], state %u =\n",
+ state.index, state.element, state.state);
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "technique %u, pass %u, state %u =\n",
+ state.technique, state.index, state.state);
+ }
+
+ size = fx_parser_read_u32(parser);
+
+ parse_fx_print_indent(parser);
+
+ if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER)
+ {
+ data = fx_parser_get_ptr(parser, size);
+ fx_print_string(&parser->buffer, "parameter \"", data, size);
+ vkd3d_string_buffer_printf(&parser->buffer, "\"\n");
+ fx_parser_skip(parser, align(size, 4));
+ }
+ else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR)
+ {
+ fx_parse_fx_2_array_selector(parser, size);
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size);
+ data = fx_parser_get_ptr(parser, size);
+ fx_dump_blob(parser, data, size);
+ fx_parser_skip(parser, align(size, 4));
+ }
+}
+
static void fx_2_parse(struct fx_parser *parser)
{
- uint32_t i, size, parameter_count, technique_count, blob_count;
+ uint32_t i, size, parameter_count, technique_count, blob_count, state_count;
fx_parser_skip(parser, sizeof(uint32_t)); /* Version */
size = fx_parser_read_u32(parser);
@@ -3931,13 +4222,20 @@ static void fx_2_parse(struct fx_parser *parser)
fx_parse_fx_2_technique(parser);
blob_count = fx_parser_read_u32(parser);
- fx_parser_read_u32(parser); /* Resource count */
+ state_count = fx_parser_read_u32(parser);
vkd3d_string_buffer_printf(&parser->buffer, "object data {\n");
parse_fx_start_indent(parser);
for (i = 0; i < blob_count; ++i)
fx_parse_fx_2_data_blob(parser);
parse_fx_end_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "}\n\n");
+
+ vkd3d_string_buffer_printf(&parser->buffer, "state data {\n");
+ parse_fx_start_indent(parser);
+ for (i = 0; i < state_count; ++i)
+ fx_parse_fx_2_complex_state(parser);
+ parse_fx_end_indent(parser);
vkd3d_string_buffer_printf(&parser->buffer, "}\n");
}
@@ -4157,17 +4455,8 @@ static void fx_parse_buffers(struct fx_parser *parser)
static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object_type, const struct fx_5_shader *shader)
{
- struct vkd3d_shader_compile_info info = { 0 };
- struct vkd3d_shader_code output;
const void *data = NULL;
- const char *p, *q, *end;
uint32_t data_size;
- int ret;
-
- static const struct vkd3d_shader_compile_option options[] =
- {
- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_15},
- };
if (!shader->offset)
{
@@ -4183,42 +4472,8 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object
if (!data)
return;
- info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
- info.source.code = data;
- info.source.size = data_size;
- info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
- info.target_type = VKD3D_SHADER_TARGET_D3D_ASM;
- info.options = options;
- info.option_count = ARRAY_SIZE(options);
- info.log_level = VKD3D_SHADER_LOG_INFO;
-
- if ((ret = vkd3d_shader_compile(&info, &output, NULL)) < 0)
- {
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
- "Failed to disassemble shader blob.");
- return;
- }
- parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "asm {\n");
-
- parse_fx_start_indent(parser);
-
- end = (const char *)output.code + output.size;
- for (p = output.code; p < end; p = q)
- {
- if (!(q = memchr(p, '\n', end - p)))
- q = end;
- else
- ++q;
-
- parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "%.*s", (int)(q - p), p);
- }
-
- parse_fx_end_indent(parser);
+ fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_DXBC_TPF, data, data_size);
- parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "}");
if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO && shader->sodecl[0])
{
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */",
@@ -4235,8 +4490,6 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object
if (shader->sodecl_count)
vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader->rast_stream);
}
-
- vkd3d_shader_free_shader_code(&output);
}
static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type)
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index a47c2feb094..801de6a5954 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -1657,6 +1657,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
case VKD3DSIH_SWITCH:
shader_glsl_switch(gen, ins);
break;
+ case VKD3DSIH_XOR:
+ shader_glsl_binop(gen, ins, "^");
+ break;
default:
shader_glsl_unhandled(gen, ins);
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 41aa99fbc09..2e3040f038e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -7706,6 +7706,29 @@ static void vsir_validate_label_register(struct validation_context *ctx,
reg->idx[0].offset, ctx->program->block_count);
}
+static void vsir_validate_constbuffer_register(struct validation_context *ctx,
+ const struct vkd3d_shader_register *reg)
+{
+ if (reg->precision != VKD3D_SHADER_REGISTER_PRECISION_DEFAULT)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION,
+ "Invalid precision %#x for a CONSTBUFFER register.", reg->precision);
+
+ if (reg->dimension != VSIR_DIMENSION_VEC4)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
+ "Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension);
+
+ if (reg->idx_count != 3)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid index count %u for a CONSTBUFFER register.", reg->idx_count);
+ return;
+ }
+
+ if (reg->idx[0].rel_addr)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX,
+ "Non-NULL relative address for a CONSTBUFFER register ID.");
+}
+
static void vsir_validate_sampler_register(struct validation_context *ctx,
const struct vkd3d_shader_register *reg)
{
@@ -7943,6 +7966,10 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_register_without_indices(ctx, reg);
break;
+ case VKD3DSPR_CONSTBUFFER:
+ vsir_validate_constbuffer_register(ctx, reg);
+ break;
+
case VKD3DSPR_PRIMID:
vsir_validate_register_without_indices(ctx, reg);
break;
@@ -8130,6 +8157,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx,
case VKD3DSPR_IMMCONST:
case VKD3DSPR_IMMCONST64:
+ case VKD3DSPR_CONSTBUFFER:
+ case VKD3DSPR_IMMCONSTBUFFER:
case VKD3DSPR_SAMPLER:
case VKD3DSPR_RESOURCE:
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 66a4a274f17..45140d44595 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -348,49 +348,12 @@ static void spirv_parser_print_instruction_offset(struct spirv_parser *parser,
parser->colours.comment, offset * sizeof(uint32_t), parser->colours.reset, suffix);
}
-static char get_escape_char(char c)
-{
- switch (c)
- {
- case '"':
- case '\\':
- return c;
- case '\t':
- return 't';
- case '\n':
- return 'n';
- case '\v':
- return 'v';
- case '\f':
- return 'f';
- case '\r':
- return 'r';
- default:
- return 0;
- }
-}
-
static void spirv_parser_print_string_literal(struct spirv_parser *parser, struct vkd3d_string_buffer *buffer,
const char *prefix, const char *s, size_t len, const char *suffix)
{
- size_t start, i;
- char c;
-
vkd3d_string_buffer_printf(buffer, "%s\"%s", prefix, parser->colours.literal);
- for (i = 0, start = 0; i < len; ++i)
- {
- if ((c = get_escape_char(s[i])))
- {
- vkd3d_string_buffer_printf(buffer, "%.*s\\%c", (int)(i - start), &s[start], c);
- start = i + 1;
- }
- else if (!isprint(s[i]))
- {
- vkd3d_string_buffer_printf(buffer, "%.*s\\%03o", (int)(i - start), &s[start], (uint8_t)s[i]);
- start = i + 1;
- }
- }
- vkd3d_string_buffer_printf(buffer, "%.*s%s\"%s", (int)(len - start), &s[start], parser->colours.reset, suffix);
+ vkd3d_string_buffer_print_string_escaped(buffer, s, len);
+ vkd3d_string_buffer_printf(buffer, "%s\"%s", parser->colours.reset, suffix);
}
static const struct spirv_parser_enumerant *spirv_parser_get_enumerant(
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index c990b496545..2a66cbdb1be 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -163,6 +163,60 @@ int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d)
return ret;
}
+static char get_escape_char(char c)
+{
+ switch (c)
+ {
+ case '"':
+ case '\\':
+ return c;
+ case '\t':
+ return 't';
+ case '\n':
+ return 'n';
+ case '\v':
+ return 'v';
+ case '\f':
+ return 'f';
+ case '\r':
+ return 'r';
+ default:
+ return 0;
+ }
+}
+
+int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len)
+{
+ size_t content_size, start, i;
+ int ret;
+ char c;
+
+ content_size = buffer->content_size;
+ for (i = 0, start = 0; i < len; ++i)
+ {
+ if ((c = get_escape_char(s[i])))
+ {
+ if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\\%c", (int)(i - start), &s[start], c)) < 0)
+ goto fail;
+ start = i + 1;
+ }
+ else if (!isprint(s[i]))
+ {
+ if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\\%03o",
+ (int)(i - start), &s[start], (uint8_t)s[i])) < 0)
+ goto fail;
+ start = i + 1;
+ }
+ }
+ if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s", (int)(len - start), &s[start])) < 0)
+ goto fail;
+ return ret;
+
+fail:
+ buffer->content_size = content_size;
+ return ret;
+}
+
void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function)
{
vkd3d_shader_trace_text_(buffer->buffer, buffer->content_size, function);
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 8329bf169b0..3a1b8d8bb64 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1565,6 +1565,7 @@ void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer);
void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t size);
int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f);
int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d);
+int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len);
int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3);
void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, struct vkd3d_string_buffer *buffer);
#define vkd3d_string_buffer_trace(buffer) \
--
2.47.2