From 2d04ceb2bf3eb640d772d63c91ff03895071892b Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes 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