diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-03ad04c89004c7f800c5b1a0ea7ba286229.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-03ad04c89004c7f800c5b1a0ea7ba286229.patch index 4bbca3d7..d386bc74 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-03ad04c89004c7f800c5b1a0ea7ba286229.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-03ad04c89004c7f800c5b1a0ea7ba286229.patch @@ -1,4 +1,4 @@ -From 0633df4d8d67331fb19a60d22494b13136b6d263 Mon Sep 17 00:00:00 2001 +From fce7894de005355e8e6b8ac475aeaf20e9c1e369 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 3 Sep 2024 07:18:49 +1000 Subject: [PATCH] Updated vkd3d to 03ad04c89004c7f800c5b1a0ea7ba28622916328. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-4889c71857ce2152a9c9e014b9f5831f96d.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-4889c71857ce2152a9c9e014b9f5831f96d.patch index efed2b41..fa82a125 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-4889c71857ce2152a9c9e014b9f5831f96d.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-4889c71857ce2152a9c9e014b9f5831f96d.patch @@ -1,4 +1,4 @@ -From e0e7620dc6f16abd9530e54a7ee32756873098ff Mon Sep 17 00:00:00 2001 +From f834612a4a88cdacebe7ab1327beb71d2ba2fd5c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 23 Oct 2024 13:50:07 +1100 Subject: [PATCH] Updated vkd3d to 4889c71857ce2152a9c9e014b9f5831f96dc349b. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-91701f83035c0d67d1ab917e0f6b73f91e8.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-91701f83035c0d67d1ab917e0f6b73f91e8.patch new file mode 100644 index 00000000..5fdad889 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-91701f83035c0d67d1ab917e0f6b73f91e8.patch @@ -0,0 +1,478 @@ +From 00aa0577c99eb55b93f4b67d42baecdc9ff9f5d2 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 24 Oct 2024 07:08:51 +1100 +Subject: [PATCH] Updated vkd3d to 91701f83035c0d67d1ab917e0f6b73f91e8583d4. + +--- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 12 -- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 15 --- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 12 -- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 105 +++++++++--------- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 - + libs/vkd3d/libs/vkd3d/device.c | 65 ++++++----- + libs/vkd3d/libs/vkd3d/resource.c | 14 ++- + libs/vkd3d/libs/vkd3d/state.c | 21 ++-- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 23 ++-- + 9 files changed, 123 insertions(+), 150 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index bbebf86e6d5..9e2eacbcfa6 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -1391,18 +1391,6 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + + if (ret < 0) + { +- WARN("Failed to parse shader.\n"); +- vsir_program_cleanup(program); +- return ret; +- } +- +- if ((ret = vkd3d_shader_parser_validate(&sm1.p, config_flags)) < 0) +- { +- WARN("Failed to validate shader after parsing, ret %d.\n", ret); +- +- if (TRACE_ON()) +- vsir_program_trace(program); +- + vsir_program_cleanup(program); + return ret; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 570af5eca5a..3235a278769 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -10603,22 +10603,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co + vkd3d_free(byte_code); + + if (ret < 0) +- { +- WARN("Failed to parse shader.\n"); +- return ret; +- } +- +- if ((ret = vkd3d_shader_parser_validate(&sm6.p, config_flags)) < 0) +- { +- WARN("Failed to validate shader after parsing, ret %d.\n", ret); +- +- if (TRACE_ON()) +- vsir_program_trace(program); +- +- sm6_parser_cleanup(&sm6); +- vsir_program_cleanup(program); + return ret; +- } + + sm6_parser_cleanup(&sm6); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index f96d300676c..c937b245559 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -2964,22 +2964,10 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con + + if (sm4.p.failed) + { +- WARN("Failed to parse shader.\n"); + vsir_program_cleanup(program); + return VKD3D_ERROR_INVALID_SHADER; + } + +- if ((ret = vkd3d_shader_parser_validate(&sm4.p, config_flags)) < 0) +- { +- WARN("Failed to validate shader after parsing, ret %d.\n", ret); +- +- if (TRACE_ON()) +- vsir_program_trace(program); +- +- vsir_program_cleanup(program); +- return ret; +- } +- + return VKD3D_OK; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index ca012d4948a..3355e18b88e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -489,13 +489,13 @@ static void vkd3d_shader_dump_shader(const struct shader_dump_data *dump_data, + if ((f = fopen(filename, "wb"))) + { + if (fwrite(data, 1, size, f) != size) +- ERR("Failed to write shader to %s.\n", filename); ++ WARN("Failed to write shader to %s.\n", filename); + if (fclose(f)) +- ERR("Failed to close stream %s.\n", filename); ++ WARN("Failed to close stream %s.\n", filename); + } + else + { +- ERR("Failed to open %s for dumping shader.\n", filename); ++ WARN("Failed to open %s for dumping shader.\n", filename); + } + } + +@@ -680,6 +680,50 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_ + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, ++ struct vkd3d_shader_message_context *message_context, struct vsir_program *program) ++{ ++ enum vkd3d_result ret; ++ ++ switch (compile_info->source_type) ++ { ++ case VKD3D_SHADER_SOURCE_D3D_BYTECODE: ++ ret = d3dbc_parse(compile_info, config_flags, message_context, program); ++ break; ++ ++ case VKD3D_SHADER_SOURCE_DXBC_TPF: ++ ret = tpf_parse(compile_info, config_flags, message_context, program); ++ break; ++ ++ case VKD3D_SHADER_SOURCE_DXBC_DXIL: ++ ret = dxil_parse(compile_info, config_flags, message_context, program); ++ break; ++ ++ default: ++ ERR("Unsupported source type %#x.\n", compile_info->source_type); ++ ret = VKD3D_ERROR_INVALID_ARGUMENT; ++ break; ++ } ++ ++ if (ret < 0) ++ { ++ WARN("Failed to parse shader.\n"); ++ return ret; ++ } ++ ++ if ((ret = vsir_program_validate(program, config_flags, compile_info->source_name, message_context)) < 0) ++ { ++ WARN("Failed to validate shader after parsing, ret %d.\n", ret); ++ ++ if (TRACE_ON()) ++ vsir_program_trace(program); ++ ++ vsir_program_cleanup(program); ++ } ++ ++ return ret; ++} ++ + void vkd3d_shader_free_messages(char *messages) + { + TRACE("messages %p.\n", messages); +@@ -1578,31 +1622,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char + uint64_t config_flags = vkd3d_shader_init_config_flags(); + struct vsir_program program; + +- switch (compile_info->source_type) +- { +- case VKD3D_SHADER_SOURCE_D3D_BYTECODE: +- ret = d3dbc_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- case VKD3D_SHADER_SOURCE_DXBC_TPF: +- ret = tpf_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- case VKD3D_SHADER_SOURCE_DXBC_DXIL: +- ret = dxil_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- default: +- ERR("Unsupported source type %#x.\n", compile_info->source_type); +- ret = VKD3D_ERROR_INVALID_ARGUMENT; +- break; +- } +- +- if (ret < 0) +- { +- WARN("Failed to parse shader.\n"); +- } +- else ++ if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) + { + ret = vsir_program_scan(&program, compile_info, &message_context, NULL); + vsir_program_cleanup(&program); +@@ -1719,38 +1739,15 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, + uint64_t config_flags = vkd3d_shader_init_config_flags(); + struct vsir_program program; + +- switch (compile_info->source_type) +- { +- case VKD3D_SHADER_SOURCE_D3D_BYTECODE: +- ret = d3dbc_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- case VKD3D_SHADER_SOURCE_DXBC_TPF: +- ret = tpf_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- case VKD3D_SHADER_SOURCE_DXBC_DXIL: +- ret = dxil_parse(compile_info, config_flags, &message_context, &program); +- break; +- +- default: +- ERR("Unsupported source type %#x.\n", compile_info->source_type); +- ret = VKD3D_ERROR_INVALID_ARGUMENT; +- break; +- } +- +- if (ret < 0) +- { +- WARN("Failed to parse shader.\n"); +- } +- else ++ if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) + { + ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context); + vsir_program_cleanup(&program); + } + } + +- vkd3d_shader_dump_shader(&dump_data, out->code, out->size, false); ++ if (ret >= 0) ++ vkd3d_shader_dump_shader(&dump_data, out->code, out->size, false); + + vkd3d_shader_message_context_trace_messages(&message_context); + if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index d6c68155ee7..5ae938e0525 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -1477,12 +1477,6 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr + void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); + +-static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser, uint64_t config_flags) +-{ +- return vsir_program_validate(parser->program, config_flags, +- parser->location.source_name, parser->message_context); +-} +- + struct vkd3d_shader_descriptor_info1 + { + enum vkd3d_shader_descriptor_type type; +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index fd0ca20838f..54a39e18a0f 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -136,7 +136,8 @@ static HRESULT vkd3d_create_vk_descriptor_heap_layout(struct d3d12_device *devic + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + }; + +- if (device->vk_info.EXT_mutable_descriptor_type && index && index != VKD3D_SET_INDEX_UAV_COUNTER ++ if (device->vk_info.EXT_mutable_descriptor_type ++ && index != VKD3D_SET_INDEX_MUTABLE && index != VKD3D_SET_INDEX_UAV_COUNTER + && device->vk_descriptor_heap_layouts[index].applicable_heap_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + device->vk_descriptor_heap_layouts[index].vk_set_layout = VK_NULL_HANDLE; +@@ -144,7 +145,7 @@ static HRESULT vkd3d_create_vk_descriptor_heap_layout(struct d3d12_device *devic + } + + binding.binding = 0; +- binding.descriptorType = (device->vk_info.EXT_mutable_descriptor_type && !index) ++ binding.descriptorType = (device->vk_info.EXT_mutable_descriptor_type && index == VKD3D_SET_INDEX_MUTABLE) + ? VK_DESCRIPTOR_TYPE_MUTABLE_EXT : device->vk_descriptor_heap_layouts[index].type; + binding.descriptorCount = device->vk_descriptor_heap_layouts[index].count; + binding.stageFlags = VK_SHADER_STAGE_ALL; +@@ -200,14 +201,20 @@ static HRESULT vkd3d_vk_descriptor_heap_layouts_init(struct d3d12_device *device + { + static const struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT] = + { +- {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, +- {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, +- {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, +- {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, +- {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, +- {VK_DESCRIPTOR_TYPE_SAMPLER, false, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER}, +- /* UAV counters */ +- {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_UNIFORM_BUFFER] = ++ {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER] = ++ {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_SAMPLED_IMAGE] = ++ {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER] = ++ {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_STORAGE_IMAGE] = ++ {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, ++ [VKD3D_SET_INDEX_SAMPLER] = ++ {VK_DESCRIPTOR_TYPE_SAMPLER, false, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER}, ++ [VKD3D_SET_INDEX_UAV_COUNTER] = ++ {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + }; + const struct vkd3d_device_descriptor_limits *limits = &device->vk_info.descriptor_limits; + enum vkd3d_vk_descriptor_set_index set; +@@ -1918,24 +1925,26 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, + && descriptor_indexing->descriptorBindingUniformTexelBufferUpdateAfterBind + && descriptor_indexing->descriptorBindingStorageTexelBufferUpdateAfterBind; + +- /* Many Vulkan implementations allow up to 8 descriptor sets. Unfortunately +- * using vkd3d with Vulkan heaps and push descriptors currently requires up +- * to 9 descriptor sets (up to one for the push descriptors, up to one for +- * the static samplers and seven for Vulkan heaps, one for each needed +- * descriptor type). If we detect such situation, we disable push +- * descriptors, which allows us to stay within the limits (not doing so is +- * fatal on many implmentations). +- * +- * It is possible that a different strategy might be used. For example, we +- * could move the static samplers to one of the seven Vulkan heaps sets. Or +- * we could decide whether to create the push descriptor set when creating +- * the root signature, depending on whether there are static samplers or +- * not. */ +- if (device->vk_info.device_limits.maxBoundDescriptorSets == 8 && device->use_vk_heaps +- && device->vk_info.KHR_push_descriptor) +- { +- TRACE("Disabling VK_KHR_push_descriptor to save a descriptor set.\n"); +- device->vk_info.KHR_push_descriptor = VK_FALSE; ++ if (device->use_vk_heaps && device->vk_info.KHR_push_descriptor) ++ { ++ /* VKD3D_SET_INDEX_COUNT for the Vulkan heaps, one for the push ++ * descriptors set and one for the static samplers set. */ ++ unsigned int descriptor_set_count = VKD3D_SET_INDEX_COUNT + 2; ++ ++ /* A mutable descriptor set can replace all those that should otherwise ++ * back the SRV-UAV-CBV descriptor heap. */ ++ if (device->vk_info.EXT_mutable_descriptor_type) ++ descriptor_set_count -= VKD3D_SET_INDEX_COUNT - (VKD3D_SET_INDEX_MUTABLE + 1); ++ ++ /* For many Vulkan implementations maxBoundDescriptorSets == 8; also, ++ * if mutable descriptors are not available the descriptor set count ++ * will be 9; so saving a descriptor set is going to be often ++ * significant. */ ++ if (descriptor_set_count > device->vk_info.device_limits.maxBoundDescriptorSets) ++ { ++ WARN("Disabling VK_KHR_push_descriptor to save a descriptor set.\n"); ++ device->vk_info.KHR_push_descriptor = VK_FALSE; ++ } + } + + if (device->use_vk_heaps) +diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c +index 6d6820d3752..1f7d90eb95f 100644 +--- a/libs/vkd3d/libs/vkd3d/resource.c ++++ b/libs/vkd3d/libs/vkd3d/resource.c +@@ -2498,7 +2498,7 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea + enum vkd3d_vk_descriptor_set_index set, end; + unsigned int i = writes->count; + +- end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_UNIFORM_BUFFER ++ end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_MUTABLE + : VKD3D_SET_INDEX_STORAGE_IMAGE; + /* Binding a shader with the wrong null descriptor type works in Windows. + * To support that here we must write one to all applicable Vulkan sets. */ +@@ -4250,7 +4250,8 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descrip + if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type + && device->vk_descriptor_heap_layouts[set].vk_set_layout) + { +- pool_sizes[pool_desc.poolSizeCount].type = (device->vk_info.EXT_mutable_descriptor_type && !set) ++ pool_sizes[pool_desc.poolSizeCount].type = ++ (device->vk_info.EXT_mutable_descriptor_type && set == VKD3D_SET_INDEX_MUTABLE) + ? VK_DESCRIPTOR_TYPE_MUTABLE_EXT : device->vk_descriptor_heap_layouts[set].type; + pool_sizes[pool_desc.poolSizeCount++].descriptorCount = desc->NumDescriptors; + } +@@ -4280,11 +4281,12 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_set(struct d3d12_descript + + if (!device->vk_descriptor_heap_layouts[set].vk_set_layout) + { +- /* Set 0 uses mutable descriptors, and this set is unused. */ +- if (!descriptor_heap->vk_descriptor_sets[0].vk_set +- && FAILED(hr = d3d12_descriptor_heap_create_descriptor_set(descriptor_heap, device, 0))) ++ /* Mutable descriptors are in use, and this set is unused. */ ++ if (!descriptor_heap->vk_descriptor_sets[VKD3D_SET_INDEX_MUTABLE].vk_set ++ && FAILED(hr = d3d12_descriptor_heap_create_descriptor_set(descriptor_heap, ++ device, VKD3D_SET_INDEX_MUTABLE))) + return hr; +- descriptor_set->vk_set = descriptor_heap->vk_descriptor_sets[0].vk_set; ++ descriptor_set->vk_set = descriptor_heap->vk_descriptor_sets[VKD3D_SET_INDEX_MUTABLE].vk_set; + descriptor_set->vk_type = device->vk_descriptor_heap_layouts[set].type; + return S_OK; + } +diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c +index 8e5ec70a577..e7476a01bd7 100644 +--- a/libs/vkd3d/libs/vkd3d/state.c ++++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -1016,7 +1016,7 @@ static void vkd3d_descriptor_heap_binding_from_descriptor_range(const struct d3d + } + else + { +- binding->set = 0; ++ binding->set = VKD3D_SET_INDEX_MUTABLE; + descriptor_set_size = descriptor_limits->sampled_image_max_descriptors; + } + } +@@ -1483,21 +1483,24 @@ static unsigned int d3d12_root_signature_copy_descriptor_set_layouts(const struc + { + const struct d3d12_device *device = root_signature->device; + enum vkd3d_vk_descriptor_set_index set; ++ VkDescriptorSetLayout vk_set_layout; + unsigned int i; + + for (i = 0; i < root_signature->vk_set_count; ++i) + vk_set_layouts[i] = root_signature->descriptor_set_layouts[i].vk_layout; + +- if (device->use_vk_heaps) ++ if (!device->use_vk_heaps) ++ return i; ++ ++ for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + { +- VkDescriptorSetLayout mutable_layout = device->vk_descriptor_heap_layouts[0].vk_set_layout; ++ vk_set_layout = device->vk_descriptor_heap_layouts[set].vk_set_layout; + +- for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) +- { +- VkDescriptorSetLayout vk_set_layout = device->vk_descriptor_heap_layouts[set].vk_set_layout; +- /* All layouts must be valid, so if null, just set it to the mutable one. */ +- vk_set_layouts[i++] = vk_set_layout ? vk_set_layout : mutable_layout; +- } ++ VKD3D_ASSERT(vk_set_layout); ++ vk_set_layouts[i++] = vk_set_layout; ++ ++ if (device->vk_info.EXT_mutable_descriptor_type && set == VKD3D_SET_INDEX_MUTABLE) ++ break; + } + + return i; +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index e6d477a5c12..97a99782d6a 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -772,14 +772,21 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev + + enum vkd3d_vk_descriptor_set_index + { +- VKD3D_SET_INDEX_UNIFORM_BUFFER = 0, +- VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER = 1, +- VKD3D_SET_INDEX_SAMPLED_IMAGE = 2, +- VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER = 3, +- VKD3D_SET_INDEX_STORAGE_IMAGE = 4, +- VKD3D_SET_INDEX_SAMPLER = 5, +- VKD3D_SET_INDEX_UAV_COUNTER = 6, +- VKD3D_SET_INDEX_COUNT = 7 ++ VKD3D_SET_INDEX_SAMPLER, ++ VKD3D_SET_INDEX_UAV_COUNTER, ++ VKD3D_SET_INDEX_MUTABLE, ++ ++ /* These are used when mutable descriptors are not available to back ++ * SRV-UAV-CBV descriptor heaps. They must stay at the end of this ++ * enumeration, so that they can be ignored when mutable descriptors are ++ * used. */ ++ VKD3D_SET_INDEX_UNIFORM_BUFFER = VKD3D_SET_INDEX_MUTABLE, ++ VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, ++ VKD3D_SET_INDEX_SAMPLED_IMAGE, ++ VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, ++ VKD3D_SET_INDEX_STORAGE_IMAGE, ++ ++ VKD3D_SET_INDEX_COUNT + }; + + extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[]; +-- +2.45.2 + diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-5eff8bf9188c401cc31ce14d42798dc3751.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-5eff8bf9188c401cc31ce14d42798dc3751.patch new file mode 100644 index 00000000..807a70ed --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-5eff8bf9188c401cc31ce14d42798dc3751.patch @@ -0,0 +1,735 @@ +From 4cffbfb94f89317c6e5ce5f7c6aa488e67a8451d Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 25 Oct 2024 07:38:01 +1100 +Subject: [PATCH] Updated vkd3d to 5eff8bf9188c401cc31ce14d42798dc3751377bd. + +--- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 112 ++++++++++++++----- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 29 +++++ + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 24 +++- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2 + + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 118 +++++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 79 ++++++------- + 6 files changed, 282 insertions(+), 82 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index a2a090e1c21..363054cb6d9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -20,8 +20,14 @@ + + struct glsl_resource_type_info + { ++ /* The number of coordinates needed to sample the resource type. */ + size_t coord_size; ++ /* Whether the resource type is an array type. */ ++ bool array; ++ /* Whether the resource type has a shadow/comparison variant. */ + bool shadow; ++ /* The type suffix for resource type. I.e., the "2D" part of "usampler2D" ++ * or "iimage2D". */ + const char *type_suffix; + }; + +@@ -102,17 +108,17 @@ static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info( + { + static const struct glsl_resource_type_info info[] = + { +- {0, 0, "None"}, /* VKD3D_SHADER_RESOURCE_NONE */ +- {1, 0, "Buffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */ +- {1, 1, "1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ +- {2, 1, "2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ +- {2, 0, "2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ +- {3, 0, "3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ +- {3, 1, "Cube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ +- {2, 1, "1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ +- {3, 1, "2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ +- {3, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ +- {4, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ ++ {0, 0, 0, "None"}, /* VKD3D_SHADER_RESOURCE_NONE */ ++ {1, 0, 0, "Buffer"}, /* VKD3D_SHADER_RESOURCE_BUFFER */ ++ {1, 0, 1, "1D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1D */ ++ {2, 0, 1, "2D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2D */ ++ {2, 0, 0, "2DMS"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMS */ ++ {3, 0, 0, "3D"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_3D */ ++ {3, 0, 1, "Cube"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBE */ ++ {2, 1, 1, "1DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ ++ {3, 1, 1, "2DArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ ++ {3, 1, 0, "2DMSArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ ++ {4, 1, 1, "CubeArray"}, /* VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY */ + }; + + if (!t || t >= ARRAY_SIZE(info)) +@@ -862,17 +868,24 @@ static void shader_glsl_print_shadow_coord(struct vkd3d_string_buffer *buffer, s + + static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { ++ bool shadow_sampler, array, bias, gather, grad, lod, lod_zero, shadow; + const struct glsl_resource_type_info *resource_type_info; + unsigned int resource_id, resource_idx, resource_space; + unsigned int sampler_id, sampler_idx, sampler_space; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_component_type sampled_type; + enum vkd3d_shader_resource_type resource_type; ++ unsigned int component_idx, coord_size; + struct vkd3d_string_buffer *sample; + enum vkd3d_data_type data_type; +- unsigned int coord_size; + struct glsl_dst dst; +- bool shadow; ++ ++ bias = ins->opcode == VKD3DSIH_SAMPLE_B; ++ gather = ins->opcode == VKD3DSIH_GATHER4; ++ grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD; ++ lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; ++ lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ; ++ shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; + + if (vkd3d_shader_instruction_has_texel_offset(ins)) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +@@ -904,12 +917,14 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) + { + coord_size = resource_type_info->coord_size; ++ array = resource_type_info->array; + } + else + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + coord_size = 2; ++ array = false; + } + + sampler_id = ins->src[2].reg.idx[0].offset; +@@ -917,17 +932,17 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + if ((d = shader_glsl_get_descriptor_by_id(gen, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) + { + sampler_space = d->register_space; +- shadow = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; ++ shadow_sampler = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + +- if (ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ) ++ if (shadow) + { +- if (!shadow) ++ if (!shadow_sampler) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Sampler %u is not a comparison sampler.", sampler_id); + } + else + { +- if (shadow) ++ if (shadow_sampler) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Sampler %u is a comparison sampler.", sampler_id); + } +@@ -942,26 +957,44 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + glsl_dst_init(&dst, gen, ins, &ins->dst[0]); + sample = vkd3d_string_buffer_get(&gen->string_buffers); + +- if (ins->opcode == VKD3DSIH_SAMPLE_C_LZ) ++ if (gather) ++ vkd3d_string_buffer_printf(sample, "textureGather("); ++ else if (grad) ++ vkd3d_string_buffer_printf(sample, "textureGrad("); ++ else if (lod) + vkd3d_string_buffer_printf(sample, "textureLod("); + else + vkd3d_string_buffer_printf(sample, "texture("); + shader_glsl_print_combined_sampler_name(sample, gen, resource_idx, resource_space, sampler_idx, sampler_space); + vkd3d_string_buffer_printf(sample, ", "); +- if (ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ) ++ if (shadow) + shader_glsl_print_shadow_coord(sample, gen, &ins->src[0], &ins->src[3], coord_size); + else + shader_glsl_print_src(sample, gen, &ins->src[0], + vkd3d_write_mask_from_component_count(coord_size), ins->src[0].reg.data_type); +- if (ins->opcode == VKD3DSIH_SAMPLE_B) ++ if (grad) + { + vkd3d_string_buffer_printf(sample, ", "); +- shader_glsl_print_src(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); ++ shader_glsl_print_src(sample, gen, &ins->src[3], ++ vkd3d_write_mask_from_component_count(coord_size - array), ins->src[3].reg.data_type); ++ vkd3d_string_buffer_printf(sample, ", "); ++ shader_glsl_print_src(sample, gen, &ins->src[4], ++ vkd3d_write_mask_from_component_count(coord_size - array), ins->src[4].reg.data_type); + } +- else if (ins->opcode == VKD3DSIH_SAMPLE_C_LZ) ++ else if (lod_zero) + { + vkd3d_string_buffer_printf(sample, ", 0.0"); + } ++ else if (bias || lod) ++ { ++ vkd3d_string_buffer_printf(sample, ", "); ++ shader_glsl_print_src(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); ++ } ++ if (gather) ++ { ++ if ((component_idx = vsir_swizzle_get_component(ins->src[2].swizzle, 0))) ++ vkd3d_string_buffer_printf(sample, ", %d", component_idx); ++ } + vkd3d_string_buffer_printf(sample, ")"); + shader_glsl_print_swizzle(sample, ins->src[1].swizzle, ins->dst[0].write_mask); + +@@ -1465,6 +1498,15 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_FTOU: + shader_glsl_cast(gen, ins, "uint", "uvec"); + break; ++ case VKD3DSIH_GATHER4: ++ case VKD3DSIH_SAMPLE: ++ case VKD3DSIH_SAMPLE_B: ++ case VKD3DSIH_SAMPLE_C: ++ case VKD3DSIH_SAMPLE_C_LZ: ++ case VKD3DSIH_SAMPLE_GRAD: ++ case VKD3DSIH_SAMPLE_LOD: ++ shader_glsl_sample(gen, ins); ++ break; + case VKD3DSIH_GEO: + case VKD3DSIH_IGE: + shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); +@@ -1482,9 +1524,11 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + break; + case VKD3DSIH_IMAX: + case VKD3DSIH_MAX: ++ case VKD3DSIH_UMAX: + shader_glsl_intrinsic(gen, ins, "max"); + break; + case VKD3DSIH_MIN: ++ case VKD3DSIH_UMIN: + shader_glsl_intrinsic(gen, ins, "min"); + break; + case VKD3DSIH_IMUL: +@@ -1553,12 +1597,6 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_RSQ: + shader_glsl_intrinsic(gen, ins, "inversesqrt"); + break; +- case VKD3DSIH_SAMPLE: +- case VKD3DSIH_SAMPLE_B: +- case VKD3DSIH_SAMPLE_C: +- case VKD3DSIH_SAMPLE_C_LZ: +- shader_glsl_sample(gen, ins); +- break; + case VKD3DSIH_SQRT: + shader_glsl_intrinsic(gen, ins, "sqrt"); + break; +@@ -2197,6 +2235,20 @@ static void shader_glsl_generate_output_declarations(struct vkd3d_glsl_generator + } + } + ++static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer, ++ struct vkd3d_glsl_generator *gen, enum vsir_global_flags flags) ++{ ++ if (flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL) ++ { ++ vkd3d_string_buffer_printf(buffer, "layout(early_fragment_tests) in;\n"); ++ flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; ++ } ++ ++ if (flags) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags); ++} ++ + static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) + { + const struct vsir_program *program = gen->program; +@@ -2210,9 +2262,7 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) + group_size->x, group_size->y, group_size->z); + } + +- if (program->global_flags) +- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)program->global_flags); ++ shader_glsl_handle_global_flags(buffer, gen, program->global_flags); + + shader_glsl_generate_descriptor_declarations(gen); + shader_glsl_generate_input_declarations(gen); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index c7aa148ea11..cafff2fa878 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -1695,6 +1695,22 @@ struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node * + return &s->node; + } + ++struct hlsl_ir_node *hlsl_new_vsir_instruction_ref(struct hlsl_ctx *ctx, unsigned int vsir_instr_idx, ++ struct hlsl_type *type, const struct hlsl_reg *reg, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_vsir_instruction_ref *vsir_instr; ++ ++ if (!(vsir_instr = hlsl_alloc(ctx, sizeof(*vsir_instr)))) ++ return NULL; ++ init_node(&vsir_instr->node, HLSL_IR_VSIR_INSTRUCTION_REF, type, loc); ++ vsir_instr->vsir_instr_idx = vsir_instr_idx; ++ ++ if (reg) ++ vsir_instr->node.reg = *reg; ++ ++ return &vsir_instr->node; ++} ++ + struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) + { +@@ -2517,6 +2533,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, + + case HLSL_IR_STATEBLOCK_CONSTANT: + return clone_stateblock_constant(ctx, map, hlsl_ir_stateblock_constant(instr)); ++ ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ vkd3d_unreachable(); + } + + vkd3d_unreachable(); +@@ -2938,6 +2957,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) + [HLSL_IR_COMPILE] = "HLSL_IR_COMPILE", + [HLSL_IR_SAMPLER_STATE] = "HLSL_IR_SAMPLER_STATE", + [HLSL_IR_STATEBLOCK_CONSTANT] = "HLSL_IR_STATEBLOCK_CONSTANT", ++ [HLSL_IR_VSIR_INSTRUCTION_REF] = "HLSL_IR_VSIR_INSTRUCTION_REF", + }; + + if (type >= ARRAY_SIZE(names)) +@@ -3531,6 +3551,11 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + case HLSL_IR_STATEBLOCK_CONSTANT: + dump_ir_stateblock_constant(buffer, hlsl_ir_stateblock_constant(instr)); + break; ++ ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ vkd3d_string_buffer_printf(buffer, "vsir_program instruction %u", ++ hlsl_ir_vsir_instruction_ref(instr)->vsir_instr_idx); ++ break; + } + } + +@@ -3839,6 +3864,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) + case HLSL_IR_STATEBLOCK_CONSTANT: + free_ir_stateblock_constant(hlsl_ir_stateblock_constant(node)); + break; ++ ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ vkd3d_free(hlsl_ir_vsir_instruction_ref(node)); ++ break; + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index e234cd0ba40..ae7f8c1c04f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -328,6 +328,8 @@ enum hlsl_ir_node_type + HLSL_IR_COMPILE, + HLSL_IR_SAMPLER_STATE, + HLSL_IR_STATEBLOCK_CONSTANT, ++ ++ HLSL_IR_VSIR_INSTRUCTION_REF, + }; + + /* Common data for every type of IR instruction node. */ +@@ -930,6 +932,16 @@ struct hlsl_ir_stateblock_constant + char *name; + }; + ++/* A vkd3d_shader_instruction that can be inserted in a hlsl_block. ++ * Only used for the HLSL IR to vsir translation, might be removed once this translation is complete. */ ++struct hlsl_ir_vsir_instruction_ref ++{ ++ struct hlsl_ir_node node; ++ ++ /* Index to a vkd3d_shader_instruction within a vkd3d_shader_instruction_array in a vsir_program. */ ++ unsigned int vsir_instr_idx; ++}; ++ + struct hlsl_scope + { + /* Item entry for hlsl_ctx.scopes. */ +@@ -1245,6 +1257,12 @@ static inline struct hlsl_ir_stateblock_constant *hlsl_ir_stateblock_constant(co + return CONTAINING_RECORD(node, struct hlsl_ir_stateblock_constant, node); + } + ++static inline struct hlsl_ir_vsir_instruction_ref *hlsl_ir_vsir_instruction_ref(const struct hlsl_ir_node *node) ++{ ++ VKD3D_ASSERT(node->type == HLSL_IR_VSIR_INSTRUCTION_REF); ++ return CONTAINING_RECORD(node, struct hlsl_ir_vsir_instruction_ref, node); ++} ++ + static inline void hlsl_block_init(struct hlsl_block *block) + { + list_init(&block->instrs); +@@ -1433,9 +1451,6 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx, + + void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body); + void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); +-uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func); +-void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func); +-void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func); + int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, + enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); + int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); +@@ -1570,6 +1585,9 @@ struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned + struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector, + struct list *cases, const struct vkd3d_shader_location *loc); + ++struct hlsl_ir_node *hlsl_new_vsir_instruction_ref(struct hlsl_ctx *ctx, unsigned int vsir_instr_idx, ++ struct hlsl_type *type, const struct hlsl_reg *reg, const struct vkd3d_shader_location *loc); ++ + void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, + enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); + void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 49cff4c81b8..cd938fd5906 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -672,6 +672,8 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx + hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Expected literal expression."); + break; ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ vkd3d_unreachable(); + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 6e1b2b437b0..2cb56d6b493 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -4162,6 +4162,9 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + case HLSL_IR_STATEBLOCK_CONSTANT: + /* Stateblock constants should not appear in the shader program. */ + vkd3d_unreachable(); ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ /* HLSL IR nodes are not translated to hlsl_ir_vsir_instruction_ref at this point. */ ++ vkd3d_unreachable(); + } + + return false; +@@ -4193,7 +4196,7 @@ static bool mark_indexable_var(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + return true; + } + +-void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) + { + struct hlsl_scope *scope; + struct hlsl_ir_var *var; +@@ -4301,6 +4304,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + case HLSL_IR_STATEBLOCK_CONSTANT: + /* Stateblock constants should not appear in the shader program. */ + vkd3d_unreachable(); ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ /* HLSL IR nodes are not translated to hlsl_ir_vsir_instruction_ref at this point. */ ++ vkd3d_unreachable(); + + case HLSL_IR_STORE: + { +@@ -4441,7 +4447,7 @@ static void init_var_liveness(struct hlsl_ir_var *var) + var->last_read = UINT_MAX; + } + +-void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) + { + struct hlsl_scope *scope; + struct hlsl_ir_var *var; +@@ -5222,7 +5228,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi + * index to all (simultaneously live) variables or intermediate values. Agnostic + * as to how many registers are actually available for the current backend, and + * does not handle constants. */ +-uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) + { + struct register_allocator allocator = {0}; + struct hlsl_scope *scope; +@@ -7536,10 +7542,101 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + sm1_generate_vsir_block(ctx, &entry_func->body, program); + } + ++static void add_last_vsir_instr_to_block(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_block *block) ++{ ++ struct vkd3d_shader_location *loc; ++ struct hlsl_ir_node *vsir_instr; ++ ++ loc = &program->instructions.elements[program->instructions.count - 1].location; ++ ++ if (!(vsir_instr = hlsl_new_vsir_instruction_ref(ctx, program->instructions.count - 1, NULL, NULL, loc))) ++ { ++ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; ++ return; ++ } ++ hlsl_block_add_instr(block, vsir_instr); ++} ++ ++static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program, ++ uint32_t temp_count, struct hlsl_block *block, const struct vkd3d_shader_location *loc) ++{ ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_TEMPS, 0, 0))) ++ return; ++ ++ ins->declaration.count = temp_count; ++ ++ add_last_vsir_instr_to_block(ctx, program, block); ++} ++ ++static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, ++ struct vsir_program *program, struct hlsl_block *block, uint32_t idx, ++ uint32_t size, uint32_t comp_count, const struct vkd3d_shader_location *loc) ++{ ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_INDEXABLE_TEMP, 0, 0))) ++ return; ++ ++ ins->declaration.indexable_temp.register_idx = idx; ++ ins->declaration.indexable_temp.register_size = size; ++ ins->declaration.indexable_temp.alignment = 0; ++ ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; ++ ins->declaration.indexable_temp.component_count = comp_count; ++ ins->declaration.indexable_temp.has_function_scope = false; ++ ++ add_last_vsir_instr_to_block(ctx, program, block); ++} ++ ++static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, ++ struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program) ++{ ++ struct hlsl_block block = {0}; ++ struct hlsl_scope *scope; ++ struct hlsl_ir_var *var; ++ uint32_t temp_count; ++ ++ compute_liveness(ctx, func); ++ mark_indexable_vars(ctx, func); ++ temp_count = allocate_temp_registers(ctx, func); ++ if (ctx->result) ++ return; ++ program->temp_count = max(program->temp_count, temp_count); ++ ++ hlsl_block_init(&block); ++ ++ if (temp_count) ++ sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc); ++ ++ LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) ++ { ++ LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) ++ { ++ if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) ++ continue; ++ if (!var->regs[HLSL_REGSET_NUMERIC].allocated) ++ continue; ++ ++ if (var->indexable) ++ { ++ unsigned int id = var->regs[HLSL_REGSET_NUMERIC].id; ++ unsigned int size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4; ++ ++ sm4_generate_vsir_instr_dcl_indexable_temp(ctx, program, &block, id, size, 4, &var->loc); ++ } ++ } ++ } ++ ++ list_move_head(&func->body.instrs, &block.instrs); ++ ++ hlsl_block_cleanup(&block); ++} ++ + /* OBJECTIVE: Translate all the information from ctx and entry_func to the + * vsir_program, so it can be used as input to tpf_compile() without relying + * on ctx and entry_func. */ +-static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, ++static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, + uint64_t config_flags, struct vsir_program *program) + { + struct vkd3d_shader_version version = {0}; +@@ -7554,9 +7651,20 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + return; + } + +- generate_vsir_signature(ctx, program, entry_func); ++ generate_vsir_signature(ctx, program, func); + if (version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_signature(ctx, program, ctx->patch_constant_func); ++ ++ if (version.type == VKD3D_SHADER_TYPE_COMPUTE) ++ { ++ program->thread_group_size.x = ctx->thread_count[0]; ++ program->thread_group_size.y = ctx->thread_count[1]; ++ program->thread_group_size.z = ctx->thread_count[2]; ++ } ++ ++ sm4_generate_vsir_add_function(ctx, func, config_flags, program); ++ if (version.type == VKD3D_SHADER_TYPE_HULL) ++ sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); + } + + static struct hlsl_ir_jump *loop_unrolling_find_jump(struct hlsl_block *block, struct hlsl_ir_node *stop_point, +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index c937b245559..2198b828b7c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3002,9 +3002,10 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, + } + register_table[] = + { +- {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADID, false}, +- {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADGROUPID, false}, +- {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_LOCALTHREADID, false}, ++ {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADID, false}, ++ {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADGROUPID, false}, ++ {"sv_groupindex", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_LOCALTHREADINDEX, false}, ++ {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_LOCALTHREADID, false}, + + {"sv_domainlocation", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3DSPR_TESSCOORD, false}, + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3DSPR_PRIMID, false}, +@@ -3105,6 +3106,7 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + { + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, ++ {"sv_groupindex", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + + {"sv_domainlocation", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, +@@ -4935,42 +4937,39 @@ static void tpf_write_dcl_semantic(const struct tpf_compiler *tpf, + write_sm4_instruction(tpf, &instr); + } + +-static void write_sm4_dcl_temps(const struct tpf_compiler *tpf, uint32_t temp_count) ++static void tpf_dcl_temps(const struct tpf_compiler *tpf, unsigned int count) + { + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_TEMPS, + +- .idx = {temp_count}, ++ .idx = {count}, + .idx_count = 1, + }; + + write_sm4_instruction(tpf, &instr); + } + +-static void write_sm4_dcl_indexable_temp(const struct tpf_compiler *tpf, uint32_t idx, +- uint32_t size, uint32_t comp_count) ++static void tpf_dcl_indexable_temp(const struct tpf_compiler *tpf, const struct vkd3d_shader_indexable_temp *temp) + { + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, + +- .idx = {idx, size, comp_count}, ++ .idx = {temp->register_idx, temp->register_size, temp->component_count}, + .idx_count = 3, + }; + + write_sm4_instruction(tpf, &instr); + } + +-static void write_sm4_dcl_thread_group(const struct tpf_compiler *tpf, const uint32_t thread_count[3]) ++static void tpf_dcl_thread_group(const struct tpf_compiler *tpf, const struct vsir_thread_group_size *group_size) + { + struct sm4_instruction instr = + { + .opcode = VKD3D_SM5_OP_DCL_THREAD_GROUP, + +- .idx[0] = thread_count[0], +- .idx[1] = thread_count[1], +- .idx[2] = thread_count[2], ++ .idx = {group_size->x, group_size->y, group_size->z}, + .idx_count = 3, + }; + +@@ -6449,9 +6448,28 @@ static void write_sm4_swizzle(const struct tpf_compiler *tpf, const struct hlsl_ + write_sm4_instruction(tpf, &instr); + } + ++static void tpf_handle_instruction(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) ++{ ++ switch (ins->opcode) ++ { ++ case VKD3DSIH_DCL_TEMPS: ++ tpf_dcl_temps(tpf, ins->declaration.count); ++ break; ++ ++ case VKD3DSIH_DCL_INDEXABLE_TEMP: ++ tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp); ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ break; ++ } ++} ++ + static void write_sm4_block(const struct tpf_compiler *tpf, const struct hlsl_block *block) + { + const struct hlsl_ir_node *instr; ++ unsigned int vsir_instr_idx; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { +@@ -6517,6 +6535,11 @@ static void write_sm4_block(const struct tpf_compiler *tpf, const struct hlsl_bl + write_sm4_swizzle(tpf, hlsl_ir_swizzle(instr)); + break; + ++ case HLSL_IR_VSIR_INSTRUCTION_REF: ++ vsir_instr_idx = hlsl_ir_vsir_instruction_ref(instr)->vsir_instr_idx; ++ tpf_handle_instruction(tpf, &tpf->program->instructions.elements[vsir_instr_idx]); ++ break; ++ + default: + hlsl_fixme(tpf->ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type)); + } +@@ -6526,15 +6549,7 @@ static void write_sm4_block(const struct tpf_compiler *tpf, const struct hlsl_bl + static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *func) + { + struct hlsl_ctx *ctx = tpf->ctx; +- const struct hlsl_scope *scope; + const struct hlsl_ir_var *var; +- uint32_t temp_count; +- +- compute_liveness(ctx, func); +- mark_indexable_vars(ctx, func); +- temp_count = allocate_temp_registers(ctx, func); +- if (ctx->result) +- return; + + LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + { +@@ -6544,29 +6559,7 @@ static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_f + } + + if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) +- write_sm4_dcl_thread_group(tpf, ctx->thread_count); +- +- if (temp_count) +- write_sm4_dcl_temps(tpf, temp_count); +- +- LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) +- { +- LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) +- { +- if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) +- continue; +- if (!var->regs[HLSL_REGSET_NUMERIC].allocated) +- continue; +- +- if (var->indexable) +- { +- unsigned int id = var->regs[HLSL_REGSET_NUMERIC].id; +- unsigned int size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4; +- +- write_sm4_dcl_indexable_temp(tpf, id, size, 4); +- } +- } +- } ++ tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size); + + write_sm4_block(tpf, &func->body); + +-- +2.45.2 + diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ad2208b726f825305f69d099790208e4e4f.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ad2208b726f825305f69d099790208e4e4f.patch new file mode 100644 index 00000000..a6b8a6da --- /dev/null +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ad2208b726f825305f69d099790208e4e4f.patch @@ -0,0 +1,971 @@ +From 96e8ac892cb6820820058ef20c96d49a28570b0e 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 +