wine-staging/patches/vkd3d-latest/0005-Updated-vkd3d-to-ad2208b726f825305f69d099790208e4e4f.patch
2024-11-01 18:00:55 +11:00

972 lines
40 KiB
Diff

From 96e8ac892cb6820820058ef20c96d49a28570b0e Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Wed, 30 Oct 2024 10:33:09 +1100
Subject: [PATCH] Updated vkd3d to ad2208b726f825305f69d099790208e4e4f85e35.
---
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 4 +
libs/vkd3d/libs/vkd3d-shader/fx.c | 322 ++++++++++++++++----
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 9 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 139 +++++++--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 30 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 14 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 45 +--
libs/vkd3d/libs/vkd3d/device.c | 2 +-
10 files changed, 442 insertions(+), 128 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index bc28aebed4d..7c5444f63a3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -1189,6 +1189,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
vkd3d_string_buffer_printf(buffer, "vWaveLaneIndex");
break;
+ case VKD3DSPR_PARAMETER:
+ vkd3d_string_buffer_printf(buffer, "parameter");
+ break;
+
case VKD3DSPR_POINT_COORD:
vkd3d_string_buffer_printf(buffer, "vPointCoord");
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index d901f08d50d..8954feb22b7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -499,7 +499,35 @@ enum fx_4_type_constants
FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000,
/* Object types */
- FX_4_OBJECT_TYPE_STRING = 1,
+ FX_4_OBJECT_TYPE_STRING = 0x1,
+ FX_4_OBJECT_TYPE_PIXEL_SHADER = 0x5,
+ FX_4_OBJECT_TYPE_VERTEX_SHADER = 0x6,
+ FX_4_OBJECT_TYPE_GEOMETRY_SHADER = 0x7,
+ FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO = 0x8,
+
+ FX_4_OBJECT_TYPE_TEXTURE = 0x9,
+ FX_4_OBJECT_TYPE_TEXTURE_1D = 0xa,
+ FX_4_OBJECT_TYPE_TEXTURE_1DARRAY = 0xb,
+ FX_4_OBJECT_TYPE_TEXTURE_2D = 0xc,
+ FX_4_OBJECT_TYPE_TEXTURE_2DARRAY = 0xd,
+ FX_4_OBJECT_TYPE_TEXTURE_2DMS = 0xe,
+ FX_4_OBJECT_TYPE_TEXTURE_2DMSARRAY = 0xf,
+ FX_4_OBJECT_TYPE_TEXTURE_3D = 0x10,
+ FX_4_OBJECT_TYPE_TEXTURE_CUBE = 0x11,
+ FX_4_OBJECT_TYPE_TEXTURE_CUBEARRAY = 0x17,
+
+ FX_5_OBJECT_TYPE_GEOMETRY_SHADER = 0x1b,
+ FX_5_OBJECT_TYPE_COMPUTE_SHADER = 0x1c,
+ FX_5_OBJECT_TYPE_HULL_SHADER = 0x1d,
+ FX_5_OBJECT_TYPE_DOMAIN_SHADER = 0x1e,
+
+ FX_5_OBJECT_TYPE_UAV_1D = 0x1f,
+ FX_5_OBJECT_TYPE_UAV_1DARRAY = 0x20,
+ FX_5_OBJECT_TYPE_UAV_2D = 0x21,
+ FX_5_OBJECT_TYPE_UAV_2DARRAY = 0x22,
+ FX_5_OBJECT_TYPE_UAV_3D = 0x23,
+ FX_5_OBJECT_TYPE_UAV_BUFFER = 0x24,
+ FX_5_OBJECT_TYPE_UAV_STRUCTURED_BUFFER = 0x28,
/* Types */
FX_4_TYPE_CLASS_NUMERIC = 1,
@@ -764,16 +792,16 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
{
static const uint32_t texture_type[] =
{
- [HLSL_SAMPLER_DIM_GENERIC] = 9,
- [HLSL_SAMPLER_DIM_1D] = 10,
- [HLSL_SAMPLER_DIM_1DARRAY] = 11,
- [HLSL_SAMPLER_DIM_2D] = 12,
- [HLSL_SAMPLER_DIM_2DARRAY] = 13,
- [HLSL_SAMPLER_DIM_2DMS] = 14,
- [HLSL_SAMPLER_DIM_2DMSARRAY] = 15,
- [HLSL_SAMPLER_DIM_3D] = 16,
- [HLSL_SAMPLER_DIM_CUBE] = 17,
- [HLSL_SAMPLER_DIM_CUBEARRAY] = 23,
+ [HLSL_SAMPLER_DIM_GENERIC] = FX_4_OBJECT_TYPE_TEXTURE,
+ [HLSL_SAMPLER_DIM_1D] = FX_4_OBJECT_TYPE_TEXTURE_1D,
+ [HLSL_SAMPLER_DIM_1DARRAY] = FX_4_OBJECT_TYPE_TEXTURE_1DARRAY,
+ [HLSL_SAMPLER_DIM_2D] = FX_4_OBJECT_TYPE_TEXTURE_2D,
+ [HLSL_SAMPLER_DIM_2DARRAY] = FX_4_OBJECT_TYPE_TEXTURE_2DARRAY,
+ [HLSL_SAMPLER_DIM_2DMS] = FX_4_OBJECT_TYPE_TEXTURE_2DMS,
+ [HLSL_SAMPLER_DIM_2DMSARRAY] = FX_4_OBJECT_TYPE_TEXTURE_2DMSARRAY,
+ [HLSL_SAMPLER_DIM_3D] = FX_4_OBJECT_TYPE_TEXTURE_3D,
+ [HLSL_SAMPLER_DIM_CUBE] = FX_4_OBJECT_TYPE_TEXTURE_CUBE,
+ [HLSL_SAMPLER_DIM_CUBEARRAY] = FX_4_OBJECT_TYPE_TEXTURE_CUBEARRAY,
};
put_u32_unaligned(buffer, texture_type[element_type->sampler_dim]);
@@ -786,13 +814,13 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
{
static const uint32_t uav_type[] =
{
- [HLSL_SAMPLER_DIM_1D] = 31,
- [HLSL_SAMPLER_DIM_1DARRAY] = 32,
- [HLSL_SAMPLER_DIM_2D] = 33,
- [HLSL_SAMPLER_DIM_2DARRAY] = 34,
- [HLSL_SAMPLER_DIM_3D] = 35,
- [HLSL_SAMPLER_DIM_BUFFER] = 36,
- [HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = 40,
+ [HLSL_SAMPLER_DIM_1D] = FX_5_OBJECT_TYPE_UAV_1D,
+ [HLSL_SAMPLER_DIM_1DARRAY] = FX_5_OBJECT_TYPE_UAV_1DARRAY,
+ [HLSL_SAMPLER_DIM_2D] = FX_5_OBJECT_TYPE_UAV_2D,
+ [HLSL_SAMPLER_DIM_2DARRAY] = FX_5_OBJECT_TYPE_UAV_2DARRAY,
+ [HLSL_SAMPLER_DIM_3D] = FX_5_OBJECT_TYPE_UAV_3D,
+ [HLSL_SAMPLER_DIM_BUFFER] = FX_5_OBJECT_TYPE_UAV_BUFFER,
+ [HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = FX_5_OBJECT_TYPE_UAV_STRUCTURED_BUFFER,
};
put_u32_unaligned(buffer, uav_type[element_type->sampler_dim]);
@@ -807,11 +835,11 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
}
else if (element_type->class == HLSL_CLASS_PIXEL_SHADER)
{
- put_u32_unaligned(buffer, 5);
+ put_u32_unaligned(buffer, FX_4_OBJECT_TYPE_PIXEL_SHADER);
}
else if (element_type->class == HLSL_CLASS_VERTEX_SHADER)
{
- put_u32_unaligned(buffer, 6);
+ put_u32_unaligned(buffer, FX_4_OBJECT_TYPE_VERTEX_SHADER);
}
else if (element_type->class == HLSL_CLASS_RASTERIZER_STATE)
{
@@ -836,15 +864,15 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
}
else if (element_type->class == HLSL_CLASS_COMPUTE_SHADER)
{
- put_u32_unaligned(buffer, 28);
+ put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_COMPUTE_SHADER);
}
else if (element_type->class == HLSL_CLASS_HULL_SHADER)
{
- put_u32_unaligned(buffer, 29);
+ put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_HULL_SHADER);
}
else if (element_type->class == HLSL_CLASS_DOMAIN_SHADER)
{
- put_u32_unaligned(buffer, 30);
+ put_u32_unaligned(buffer, FX_5_OBJECT_TYPE_DOMAIN_SHADER);
}
else
{
@@ -1568,20 +1596,17 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s
for (i = 0; i < count; ++i)
{
- if (hlsl_is_numeric_type(data_type))
+ switch (data_type->e.numeric.type)
{
- switch (data_type->e.numeric.type)
- {
- case HLSL_TYPE_FLOAT:
- case HLSL_TYPE_INT:
- case HLSL_TYPE_UINT:
- case HLSL_TYPE_BOOL:
- type = fx_4_numeric_base_types[data_type->e.numeric.type];
- break;
- default:
- type = 0;
- hlsl_fixme(ctx, &ctx->location, "Unsupported numeric state value type %u.", data_type->e.numeric.type);
- }
+ case HLSL_TYPE_FLOAT:
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ case HLSL_TYPE_BOOL:
+ type = fx_4_numeric_base_types[data_type->e.numeric.type];
+ break;
+ default:
+ type = 0;
+ hlsl_fixme(ctx, &ctx->location, "Unsupported numeric state value type %u.", data_type->e.numeric.type);
}
put_u32_unaligned(buffer, type);
@@ -2922,19 +2947,28 @@ static int fx_2_parse(struct fx_parser *parser)
return -1;
}
-static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size)
+static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint32_t offset, size_t size)
{
const uint8_t *ptr = parser->unstructured.ptr;
- memset(dst, 0, size);
if (offset >= parser->unstructured.size
|| size > parser->unstructured.size - offset)
{
parser->failed = true;
- return;
+ return NULL;
}
- ptr += offset;
+ return &ptr[offset];
+}
+
+static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size)
+{
+ const uint8_t *ptr;
+
+ memset(dst, 0, size);
+ if (!(ptr = fx_parser_get_unstructured_ptr(parser, offset, size)))
+ return;
+
memcpy(dst, ptr, size);
}
@@ -3164,6 +3198,188 @@ static void fx_parse_buffers(struct fx_parser *parser)
}
}
+static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type)
+{
+ struct vkd3d_shader_compile_info info = { 0 };
+ struct vkd3d_shader_code output;
+ uint32_t data_size, offset;
+ const void *data = NULL;
+ const char *p, *q, *end;
+ struct fx_5_shader
+ {
+ uint32_t offset;
+ uint32_t sodecl[4];
+ uint32_t sodecl_count;
+ uint32_t rast_stream;
+ uint32_t iface_bindings_count;
+ uint32_t iface_bindings;
+ } shader5;
+ struct fx_4_gs_so
+ {
+ uint32_t offset;
+ uint32_t sodecl;
+ } gs_so;
+ int ret;
+
+ static const struct vkd3d_shader_compile_option options[] =
+ {
+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_13},
+ };
+
+ switch (object_type)
+ {
+ case FX_4_OBJECT_TYPE_PIXEL_SHADER:
+ case FX_4_OBJECT_TYPE_VERTEX_SHADER:
+ case FX_4_OBJECT_TYPE_GEOMETRY_SHADER:
+ offset = fx_parser_read_u32(parser);
+ break;
+
+ case FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO:
+ fx_parser_read_u32s(parser, &gs_so, sizeof(gs_so));
+ offset = gs_so.offset;
+ break;
+
+ case FX_5_OBJECT_TYPE_GEOMETRY_SHADER:
+ case FX_5_OBJECT_TYPE_COMPUTE_SHADER:
+ case FX_5_OBJECT_TYPE_HULL_SHADER:
+ case FX_5_OBJECT_TYPE_DOMAIN_SHADER:
+ fx_parser_read_u32s(parser, &shader5, sizeof(shader5));
+ offset = shader5.offset;
+ break;
+
+ default:
+ parser->failed = true;
+ return;
+ }
+
+ fx_parser_read_unstructured(parser, &data_size, offset, sizeof(data_size));
+ if (data_size)
+ data = fx_parser_get_unstructured_ptr(parser, offset + 4, data_size);
+
+ 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.\n");
+ 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, "}");
+ if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER && gs_so.sodecl)
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */",
+ fx_4_get_string(parser, gs_so.sodecl));
+ }
+ else if (object_type == FX_5_OBJECT_TYPE_GEOMETRY_SHADER)
+ {
+ for (unsigned int i = 0; i < ARRAY_SIZE(shader5.sodecl); ++i)
+ {
+ if (shader5.sodecl[i])
+ vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output %u declaration: \"%s\" */",
+ i, fx_4_get_string(parser, shader5.sodecl[i]));
+ }
+ if (shader5.sodecl_count)
+ vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader5.rast_stream);
+ }
+
+ vkd3d_shader_free_shader_code(&output);
+}
+
+static bool fx_4_is_shader_resource(const struct fx_4_binary_type *type)
+{
+ switch (type->typeinfo)
+ {
+ case FX_4_OBJECT_TYPE_TEXTURE:
+ case FX_4_OBJECT_TYPE_TEXTURE_1D:
+ case FX_4_OBJECT_TYPE_TEXTURE_1DARRAY:
+ case FX_4_OBJECT_TYPE_TEXTURE_2D:
+ case FX_4_OBJECT_TYPE_TEXTURE_2DARRAY:
+ case FX_4_OBJECT_TYPE_TEXTURE_2DMS:
+ case FX_4_OBJECT_TYPE_TEXTURE_2DMSARRAY:
+ case FX_4_OBJECT_TYPE_TEXTURE_3D:
+ case FX_4_OBJECT_TYPE_TEXTURE_CUBE:
+ case FX_4_OBJECT_TYPE_TEXTURE_CUBEARRAY:
+ case FX_5_OBJECT_TYPE_UAV_1D:
+ case FX_5_OBJECT_TYPE_UAV_1DARRAY:
+ case FX_5_OBJECT_TYPE_UAV_2D:
+ case FX_5_OBJECT_TYPE_UAV_2DARRAY:
+ case FX_5_OBJECT_TYPE_UAV_3D:
+ case FX_5_OBJECT_TYPE_UAV_BUFFER:
+ case FX_5_OBJECT_TYPE_UAV_STRUCTURED_BUFFER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct fx_4_binary_type *type)
+{
+ unsigned int i, element_count;
+ uint32_t value;
+
+ vkd3d_string_buffer_printf(&parser->buffer, " = {\n");
+ element_count = max(type->element_count, 1);
+ for (i = 0; i < element_count; ++i)
+ {
+ switch (type->typeinfo)
+ {
+ case FX_4_OBJECT_TYPE_STRING:
+ vkd3d_string_buffer_printf(&parser->buffer, " ");
+ value = fx_parser_read_u32(parser);
+ fx_4_parse_string_initializer(parser, value);
+ break;
+ case FX_4_OBJECT_TYPE_PIXEL_SHADER:
+ case FX_4_OBJECT_TYPE_VERTEX_SHADER:
+ case FX_4_OBJECT_TYPE_GEOMETRY_SHADER:
+ case FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO:
+ case FX_5_OBJECT_TYPE_GEOMETRY_SHADER:
+ case FX_5_OBJECT_TYPE_COMPUTE_SHADER:
+ case FX_5_OBJECT_TYPE_HULL_SHADER:
+ case FX_5_OBJECT_TYPE_DOMAIN_SHADER:
+ parse_fx_start_indent(parser);
+ fx_4_parse_shader_initializer(parser, type->typeinfo);
+ parse_fx_end_indent(parser);
+ break;
+ default:
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED,
+ "Parsing object type %u is not implemented.", type->typeinfo);
+ return;
+ }
+ vkd3d_string_buffer_printf(&parser->buffer, ",\n");
+ }
+ vkd3d_string_buffer_printf(&parser->buffer, "}");
+}
+
static void fx_4_parse_objects(struct fx_parser *parser)
{
struct fx_4_object_variable
@@ -3173,9 +3389,9 @@ static void fx_4_parse_objects(struct fx_parser *parser)
uint32_t semantic;
uint32_t bind_point;
} var;
- uint32_t i, j, value, element_count;
struct fx_4_binary_type type;
const char *name, *type_name;
+ uint32_t i;
if (parser->failed)
return;
@@ -3190,26 +3406,12 @@ static void fx_4_parse_objects(struct fx_parser *parser)
vkd3d_string_buffer_printf(&parser->buffer, "%s %s", type_name, name);
if (type.element_count)
vkd3d_string_buffer_printf(&parser->buffer, "[%u]", type.element_count);
- vkd3d_string_buffer_printf(&parser->buffer, " = {\n");
- element_count = max(type.element_count, 1);
- for (j = 0; j < element_count; ++j)
- {
- switch (type.typeinfo)
- {
- case FX_4_OBJECT_TYPE_STRING:
- vkd3d_string_buffer_printf(&parser->buffer, " ");
- value = fx_parser_read_u32(parser);
- fx_4_parse_string_initializer(parser, value);
- break;
- default:
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED,
- "Parsing object type %u is not implemented.\n", type.typeinfo);
- return;
- }
- vkd3d_string_buffer_printf(&parser->buffer, ",\n");
- }
- vkd3d_string_buffer_printf(&parser->buffer, "};\n");
+ if (!fx_4_is_shader_resource(&type))
+ fx_4_parse_object_initializer(parser, &type);
+ vkd3d_string_buffer_printf(&parser->buffer, ";\n");
+
+ fx_parse_fx_4_annotations(parser);
}
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index cafff2fa878..1f90a4ba805 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -2799,6 +2799,11 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
return string;
case HLSL_CLASS_UAV:
+ if (type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ {
+ vkd3d_string_buffer_printf(string, "RWByteAddressBuffer");
+ return string;
+ }
if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
vkd3d_string_buffer_printf(string, "RWBuffer");
else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
@@ -4445,8 +4450,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
rb_destroy(&ctx->functions, free_function_rb, NULL);
- hlsl_block_cleanup(&ctx->static_initializers);
-
/* State blocks must be free before the variables, because they contain instructions that may
* refer to them. */
LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &ctx->scopes, struct hlsl_scope, entry)
@@ -4462,6 +4465,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
}
}
+ hlsl_block_cleanup(&ctx->static_initializers);
+
LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &ctx->scopes, struct hlsl_scope, entry)
{
LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index ae7f8c1c04f..f890784bb8f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -136,7 +136,8 @@ enum hlsl_sampler_dim
HLSL_SAMPLER_DIM_CUBEARRAY,
HLSL_SAMPLER_DIM_BUFFER,
HLSL_SAMPLER_DIM_STRUCTURED_BUFFER,
- HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER,
+ HLSL_SAMPLER_DIM_RAW_BUFFER,
+ HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_RAW_BUFFER,
/* NOTE: Remember to update object_methods[] in hlsl.y if this enum is modified. */
};
@@ -1394,6 +1395,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim)
{
case HLSL_SAMPLER_DIM_1D:
case HLSL_SAMPLER_DIM_BUFFER:
+ case HLSL_SAMPLER_DIM_RAW_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return 1;
case HLSL_SAMPLER_DIM_1DARRAY:
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index ca983fc5ffd..18effcc5be1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -127,6 +127,7 @@ RenderTargetView {return KW_RENDERTARGETVIEW; }
return {return KW_RETURN; }
row_major {return KW_ROW_MAJOR; }
RWBuffer {return KW_RWBUFFER; }
+RWByteAddressBuffer {return KW_RWBYTEADDRESSBUFFER; }
RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; }
RWTexture1D {return KW_RWTEXTURE1D; }
RWTexture1DArray {return KW_RWTEXTURE1DARRAY; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index cd938fd5906..dcbba46ede6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -332,6 +332,9 @@ static void check_condition_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node
{
const struct hlsl_type *type = cond->data_type;
+ if (type->class == HLSL_CLASS_ERROR)
+ return;
+
if (type->class > HLSL_CLASS_LAST_NUMERIC || type->dimx > 1 || type->dimy > 1)
{
struct vkd3d_string_buffer *string;
@@ -644,6 +647,9 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
struct hlsl_block expr;
struct hlsl_src src;
+ if (node_from_block(block)->data_type->class == HLSL_CLASS_ERROR)
+ return ret;
+
LIST_FOR_EACH_ENTRY(node, &block->instrs, struct hlsl_ir_node, entry)
{
switch (node->type)
@@ -938,6 +944,9 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block,
{
struct hlsl_ir_node *store;
+ if (return_value->data_type->class == HLSL_CLASS_ERROR)
+ return true;
+
if (!(return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc)))
return false;
@@ -1234,7 +1243,8 @@ static bool add_record_access_recurse(struct hlsl_ctx *ctx, struct hlsl_block *b
}
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", name);
- return false;
+ block->value = ctx->error_instr;
+ return true;
}
static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, struct list *list)
@@ -5569,6 +5579,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim)
case HLSL_SAMPLER_DIM_CUBE:
case HLSL_SAMPLER_DIM_CUBEARRAY:
case HLSL_SAMPLER_DIM_BUFFER:
+ case HLSL_SAMPLER_DIM_RAW_BUFFER:
/* Offset parameters not supported for these types. */
return 0;
default:
@@ -6186,32 +6197,85 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block
return true;
}
+static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_node *offset, *rhs, *store;
+ struct hlsl_deref resource_deref;
+ unsigned int value_dim;
+
+ if (params->args_count != 2)
+ {
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Wrong number of arguments to method '%s': expected 2.", name);
+ return false;
+ }
+
+ if (!strcmp(name, "Store"))
+ value_dim = 1;
+ else if (!strcmp(name, "Store2"))
+ value_dim = 2;
+ else if (!strcmp(name, "Store3"))
+ value_dim = 3;
+ else
+ value_dim = 4;
+
+ if (!(offset = add_implicit_conversion(ctx, block, params->args[0],
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
+ return false;
+
+ if (!(rhs = add_implicit_conversion(ctx, block, params->args[1],
+ hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc)))
+ return false;
+
+ if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
+ return false;
+
+ if (!(store = hlsl_new_resource_store(ctx, &resource_deref, offset, rhs, loc)))
+ {
+ hlsl_cleanup_deref(&resource_deref);
+ return false;
+ }
+
+ hlsl_block_add_instr(block, store);
+ hlsl_cleanup_deref(&resource_deref);
+
+ return true;
+}
+
static const struct method_function
{
const char *name;
bool (*handler)(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc);
- bool valid_dims[HLSL_SAMPLER_DIM_MAX + 1];
+ char valid_dims[HLSL_SAMPLER_DIM_MAX + 1];
}
-object_methods[] =
+texture_methods[] =
{
- /* g c 1d 2d 3d cube 1darr 2darr 2dms 2dmsarr cubearr buff sbuff*/
- { "Gather", add_gather_method_call, {0,0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}},
- { "GatherAlpha", add_gather_method_call, {0,0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}},
- { "GatherBlue", add_gather_method_call, {0,0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}},
- { "GatherGreen", add_gather_method_call, {0,0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}},
- { "GatherRed", add_gather_method_call, {0,0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}},
+ { "Gather", add_gather_method_call, "00010101001000" },
+ { "GatherAlpha", add_gather_method_call, "00010101001000" },
+ { "GatherBlue", add_gather_method_call, "00010101001000" },
+ { "GatherGreen", add_gather_method_call, "00010101001000" },
+ { "GatherRed", add_gather_method_call, "00010101001000" },
+
+ { "GetDimensions", add_getdimensions_method_call, "00111111111110" },
- { "GetDimensions", add_getdimensions_method_call, {0,0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
+ { "Load", add_load_method_call, "00111011110110" },
- { "Load", add_load_method_call, {0,0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1}},
+ { "Sample", add_sample_method_call, "00111111001000" },
+ { "SampleBias", add_sample_lod_method_call, "00111111001000" },
+ { "SampleCmp", add_sample_cmp_method_call, "00111111001000" },
+ { "SampleCmpLevelZero", add_sample_cmp_method_call, "00111111001000" },
+ { "SampleGrad", add_sample_grad_method_call, "00111111001000" },
+ { "SampleLevel", add_sample_lod_method_call, "00111111001000" },
+};
- { "Sample", add_sample_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
- { "SampleBias", add_sample_lod_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
- { "SampleCmp", add_sample_cmp_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
- { "SampleCmpLevelZero", add_sample_cmp_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
- { "SampleGrad", add_sample_grad_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
- { "SampleLevel", add_sample_lod_method_call, {0,0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0}},
+static const struct method_function uav_methods[] =
+{
+ { "Store", add_store_method_call, "00000000000001" },
+ { "Store2", add_store_method_call, "00000000000001" },
+ { "Store3", add_store_method_call, "00000000000001" },
+ { "Store4", add_store_method_call, "00000000000001" },
};
static int object_method_function_name_compare(const void *a, const void *b)
@@ -6225,7 +6289,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
const struct hlsl_type *object_type = object->data_type;
- const struct method_function *method;
+ const struct method_function *method, *methods;
+ unsigned int count;
if (object_type->class == HLSL_CLASS_ERROR)
{
@@ -6242,7 +6307,17 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
}
}
- if (object_type->class != HLSL_CLASS_TEXTURE || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC)
+ if (object_type->class == HLSL_CLASS_TEXTURE)
+ {
+ count = ARRAY_SIZE(texture_methods);
+ methods = texture_methods;
+ }
+ else if (object_type->class == HLSL_CLASS_UAV)
+ {
+ count = ARRAY_SIZE(uav_methods);
+ methods = uav_methods;
+ }
+ else
{
struct vkd3d_string_buffer *string;
@@ -6253,10 +6328,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
return false;
}
- method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), sizeof(*method),
+ method = bsearch(name, methods, count, sizeof(*method),
object_method_function_name_compare);
- if (method && method->valid_dims[object_type->sampler_dim])
+ if (method && method->valid_dims[object_type->sampler_dim] == '1')
{
return method->handler(ctx, block, object, name, params, loc);
}
@@ -6483,6 +6558,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%token KW_REGISTER
%token KW_ROW_MAJOR
%token KW_RWBUFFER
+%token KW_RWBYTEADDRESSBUFFER
%token KW_RWSTRUCTUREDBUFFER
%token KW_RWTEXTURE1D
%token KW_RWTEXTURE1DARRAY
@@ -7797,6 +7873,10 @@ type_no_void:
validate_uav_type(ctx, $1, $3, &@4);
$$ = hlsl_new_uav_type(ctx, $1, $3, true);
}
+ | KW_RWBYTEADDRESSBUFFER
+ {
+ $$ = hlsl_new_uav_type(ctx, HLSL_SAMPLER_DIM_RAW_BUFFER, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), false);
+ }
| KW_STRING
{
$$ = ctx->builtin_types.string;
@@ -8948,30 +9028,31 @@ postfix_expr:
{
if (!add_record_access_recurse(ctx, $1, $3, &@2))
{
+ destroy_block($1);
vkd3d_free($3);
YYABORT;
}
- vkd3d_free($3);
}
else if (hlsl_is_numeric_type(node->data_type))
{
struct hlsl_ir_node *swizzle;
- if (!(swizzle = get_swizzle(ctx, node, $3, &@3)))
+ if ((swizzle = get_swizzle(ctx, node, $3, &@3)))
+ {
+ hlsl_block_add_instr($1, swizzle);
+ }
+ else
{
hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3);
- vkd3d_free($3);
- YYABORT;
+ $1->value = ctx->error_instr;
}
- hlsl_block_add_instr($1, swizzle);
- vkd3d_free($3);
}
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->value = ctx->error_instr;
}
+ vkd3d_free($3);
$$ = $1;
}
| postfix_expr '[' expr ']'
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 2cb56d6b493..ce431ee6815 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -4567,38 +4567,38 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a
unsigned int first_write, unsigned int last_read, unsigned int reg_size,
unsigned int component_count, int mode, bool force_align)
{
+ struct hlsl_reg ret = {.allocation_size = 1, .allocated = true};
unsigned int required_size = force_align ? 4 : reg_size;
- unsigned int writemask = 0, pref;
- struct hlsl_reg ret = {0};
- uint32_t reg_idx;
+ unsigned int pref;
VKD3D_ASSERT(component_count <= reg_size);
pref = allocator->prioritize_smaller_writemasks ? 4 : required_size;
for (; pref >= required_size; --pref)
{
- for (reg_idx = 0; pref == required_size || reg_idx < allocator->reg_count; ++reg_idx)
+ for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx)
{
unsigned int available_writemask = get_available_writemask(allocator,
first_write, last_read, reg_idx, mode);
if (vkd3d_popcount(available_writemask) >= pref)
{
- writemask = hlsl_combine_writemasks(available_writemask, (1u << reg_size) - 1);
- break;
+ unsigned int writemask = hlsl_combine_writemasks(available_writemask,
+ vkd3d_write_mask_from_component_count(reg_size));
+
+ ret.id = reg_idx;
+ ret.writemask = hlsl_combine_writemasks(writemask,
+ vkd3d_write_mask_from_component_count(component_count));
+ record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode);
+ return ret;
}
}
- if (writemask)
- break;
}
- VKD3D_ASSERT(vkd3d_popcount(writemask) == reg_size);
- record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode);
-
- ret.id = reg_idx;
- ret.allocation_size = 1;
- ret.writemask = hlsl_combine_writemasks(writemask, (1u << component_count) - 1);
- ret.allocated = true;
+ ret.id = allocator->reg_count;
+ ret.writemask = vkd3d_write_mask_from_component_count(component_count);
+ record_allocation(ctx, allocator, allocator->reg_count,
+ vkd3d_write_mask_from_component_count(reg_size), first_write, last_read, mode);
return ret;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 802fe221747..fb7ce063c85 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -1913,7 +1913,11 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
uint32_t scalar_id, type_id;
VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT);
- VKD3D_ASSERT(1 <= component_count && component_count <= VKD3D_VEC4_SIZE);
+ if (!component_count || component_count > VKD3D_VEC4_SIZE)
+ {
+ ERR("Invalid component count %u.\n", component_count);
+ return 0;
+ }
if ((type_id = builder->numeric_type_ids[component_type][component_count - 1]))
return type_id;
@@ -3192,6 +3196,14 @@ static bool spirv_compiler_get_register_name(char *buffer, unsigned int buffer_s
case VKD3DSPR_CONSTBUFFER:
snprintf(buffer, buffer_size, "cb%u_%u", reg->idx[0].offset, reg->idx[1].offset);
break;
+ case VKD3DSPR_RASTOUT:
+ if (idx == VSIR_RASTOUT_POINT_SIZE)
+ {
+ snprintf(buffer, buffer_size, "oPts");
+ break;
+ }
+ FIXME("Unhandled rastout register %#x.\n", idx);
+ return false;
case VKD3DSPR_INPUT:
snprintf(buffer, buffer_size, "v%u", idx);
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 2198b828b7c..befe5eacf9c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -3491,6 +3491,7 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ
case HLSL_SAMPLER_DIM_CUBEARRAY:
return D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
case HLSL_SAMPLER_DIM_BUFFER:
+ case HLSL_SAMPLER_DIM_RAW_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return D3D_SRV_DIMENSION_BUFFER;
default:
@@ -4019,6 +4020,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ
case HLSL_SAMPLER_DIM_CUBEARRAY:
return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY;
case HLSL_SAMPLER_DIM_BUFFER:
+ case HLSL_SAMPLER_DIM_RAW_BUFFER:
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
return VKD3D_SM4_RESOURCE_BUFFER;
default:
@@ -4808,6 +4810,9 @@ static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct
instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4;
break;
+ case HLSL_SAMPLER_DIM_RAW_BUFFER:
+ instr.opcode = VKD3D_SM5_OP_DCL_UAV_RAW;
+ break;
default:
instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
break;
@@ -5548,24 +5553,6 @@ static void write_sm4_cast(const struct tpf_compiler *tpf, const struct hlsl_ir_
}
}
-static void write_sm4_store_uav_typed(const struct tpf_compiler *tpf, const struct hlsl_deref *dst,
- const struct hlsl_ir_node *coords, const struct hlsl_ir_node *value)
-{
- struct sm4_instruction instr;
-
- memset(&instr, 0, sizeof(instr));
- instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED;
-
- sm4_register_from_deref(tpf, &instr.dsts[0].reg, &instr.dsts[0].write_mask, dst, &instr);
- instr.dst_count = 1;
-
- sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
- sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL);
- instr.src_count = 2;
-
- write_sm4_instruction(tpf, &instr);
-}
-
static void write_sm4_rasterizer_sample_count(const struct tpf_compiler *tpf, const struct hlsl_ir_node *dst)
{
struct sm4_instruction instr;
@@ -6352,6 +6339,8 @@ static void write_sm4_resource_load(const struct tpf_compiler *tpf, const struct
static void write_sm4_resource_store(const struct tpf_compiler *tpf, const struct hlsl_ir_resource_store *store)
{
struct hlsl_type *resource_type = hlsl_deref_get_type(tpf->ctx, &store->resource);
+ struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node;
+ struct sm4_instruction instr;
if (!store->resource.var->is_uniform)
{
@@ -6365,7 +6354,25 @@ static void write_sm4_resource_store(const struct tpf_compiler *tpf, const struc
return;
}
- write_sm4_store_uav_typed(tpf, &store->resource, store->coords.node, store->value.node);
+ memset(&instr, 0, sizeof(instr));
+
+ sm4_register_from_deref(tpf, &instr.dsts[0].reg, &instr.dsts[0].write_mask, &store->resource, &instr);
+ instr.dst_count = 1;
+ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ {
+ instr.opcode = VKD3D_SM5_OP_STORE_RAW;
+ instr.dsts[0].write_mask = vkd3d_write_mask_from_component_count(value->data_type->dimx);
+ }
+ else
+ {
+ instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED;
+ }
+
+ sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL);
+ sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL);
+ instr.src_count = 2;
+
+ write_sm4_instruction(tpf, &instr);
}
static void write_sm4_store(const struct tpf_compiler *tpf, const struct hlsl_ir_store *store)
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 54a39e18a0f..f2009a64bd2 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -1696,7 +1696,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing;
VkPhysicalDevice physical_device = device->vk_physical_device;
struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
- VkExtensionProperties *vk_extensions;
+ VkExtensionProperties *vk_extensions = NULL;
VkPhysicalDeviceFeatures *features;
uint32_t vk_extension_count;
HRESULT hr;
--
2.45.2