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
|
|
|
|
|
|