diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c index ce780b9ecbe..6873c38e664 100644 --- a/src/nouveau/vulkan/nvk_buffer.c +++ b/src/nouveau/vulkan/nvk_buffer.c @@ -7,6 +7,7 @@ #include "nvk_entrypoints.h" #include "nvk_device.h" #include "nvk_device_memory.h" +#include "nvk_instance.h" #include "nvk_physical_device.h" #include "nvk_queue.h" #include "nvkmd/nvkmd.h" @@ -20,13 +21,14 @@ nvk_get_buffer_alignment(const struct nvk_physical_device *pdev, VkBufferUsageFlags2KHR usage_flags, VkBufferCreateFlags create_flags) { + const struct nvk_instance *instance = nvk_physical_device_instance(pdev); uint32_t alignment = 16; if (usage_flags & VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT_KHR) alignment = MAX2(alignment, nvk_min_cbuf_alignment(&pdev->info)); if (usage_flags & VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR) - alignment = MAX2(alignment, NVK_MIN_SSBO_ALIGNMENT); + alignment = MAX2(alignment, nvk_min_ssbo_alignment(instance)); if (usage_flags & (VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR | VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR)) diff --git a/src/nouveau/vulkan/nvk_descriptor_set.c b/src/nouveau/vulkan/nvk_descriptor_set.c index b9dcbe08426..c85a9b6ca98 100644 --- a/src/nouveau/vulkan/nvk_descriptor_set.c +++ b/src/nouveau/vulkan/nvk_descriptor_set.c @@ -11,6 +11,7 @@ #include "nvk_entrypoints.h" #include "nvk_format.h" #include "nvk_image_view.h" +#include "nvk_instance.h" #include "nvk_physical_device.h" #include "nvk_sampler.h" #include "nvkmd/nvkmd.h" @@ -314,12 +315,14 @@ write_dynamic_ubo_desc(struct nvk_descriptor_writer *w, } static union nvk_buffer_descriptor -ssbo_desc(struct nvk_addr_range addr_range) +ssbo_desc(const struct nvk_physical_device *pdev, + struct nvk_addr_range addr_range) { - assert(addr_range.addr % NVK_MIN_SSBO_ALIGNMENT == 0); + const struct nvk_instance *instance = nvk_physical_device_instance(pdev); + const uint32_t min_ssbo_alignment = nvk_min_ssbo_alignment(instance); assert(addr_range.range <= UINT32_MAX); - addr_range.addr = ROUND_DOWN_TO(addr_range.addr, NVK_MIN_SSBO_ALIGNMENT); + addr_range.addr = ROUND_DOWN_TO(addr_range.addr, min_ssbo_alignment); addr_range.range = align(addr_range.range, NVK_SSBO_BOUNDS_CHECK_ALIGNMENT); return (union nvk_buffer_descriptor) { .addr = { @@ -337,7 +340,7 @@ write_ssbo_desc(struct nvk_descriptor_writer *w, struct nvk_addr_range addr_range = nvk_buffer_addr_range(buffer, info->offset, info->range); - const union nvk_buffer_descriptor desc = ssbo_desc(addr_range); + const union nvk_buffer_descriptor desc = ssbo_desc(w->pdev, addr_range); write_desc(w, binding, elem, &desc, sizeof(desc)); } @@ -353,7 +356,7 @@ write_dynamic_ssbo_desc(struct nvk_descriptor_writer *w, const struct nvk_descriptor_set_binding_layout *binding_layout = &w->layout->binding[binding]; w->set->dynamic_buffers[binding_layout->dynamic_buffer_index + elem] = - ssbo_desc(addr_range); + ssbo_desc(w->pdev, addr_range); } static struct nvk_edb_buffer_view_descriptor @@ -1207,7 +1210,7 @@ nvk_GetDescriptorEXT(VkDevice _device, .range = pDescriptorInfo->data.pStorageBuffer->range, }; } - union nvk_buffer_descriptor desc = ssbo_desc(addr_range); + union nvk_buffer_descriptor desc = ssbo_desc(pdev, addr_range); assert(sizeof(desc) <= dataSize); memcpy(pDescriptor, &desc, sizeof(desc)); break; diff --git a/src/nouveau/vulkan/nvk_instance.c b/src/nouveau/vulkan/nvk_instance.c index 5a8464d0510..02d1a3f3f62 100644 --- a/src/nouveau/vulkan/nvk_instance.c +++ b/src/nouveau/vulkan/nvk_instance.c @@ -130,6 +130,15 @@ nvk_init_dri_options(struct nvk_instance *instance) instance->debug_flags |= NVK_DEBUG_ZERO_MEMORY; instance->app_layer = driQueryOptionstr(&instance->dri_options, "nvk_app_layer"); + + /* VKD3D really wants a min SSBO alignment of 4B instead of 16B because + * it's required for structure buffers. If we don't do this, it'll hack + * it behind our back and we don't really want that. We just have to trust + * it to not misalign 64-bit atomics. + */ + instance->ssbo_align_4b = + (instance->vk.app_info.engine_name != NULL && + strcmp(instance->vk.app_info.engine_name, "vkd3d") == 0); } VKAPI_ATTR VkResult VKAPI_CALL diff --git a/src/nouveau/vulkan/nvk_instance.h b/src/nouveau/vulkan/nvk_instance.h index 2303e261b33..cdf96329968 100644 --- a/src/nouveau/vulkan/nvk_instance.h +++ b/src/nouveau/vulkan/nvk_instance.h @@ -22,8 +22,15 @@ struct nvk_instance { uint8_t driver_build_sha[BLAKE3_KEY_LEN]; uint32_t force_vk_vendor; + bool ssbo_align_4b; }; VK_DEFINE_HANDLE_CASTS(nvk_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE) +static inline uint32_t +nvk_min_ssbo_alignment(const struct nvk_instance *instance) +{ + return instance->ssbo_align_4b ? 4 : 16; +} + #endif diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index 1a610c5e4c2..ed5b29c806e 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -877,7 +877,7 @@ nvk_get_device_properties(const struct nvk_instance *instance, .minMemoryMapAlignment = os_page_size, .minTexelBufferOffsetAlignment = NVK_MIN_TEXEL_BUFFER_ALIGNMENT, .minUniformBufferOffsetAlignment = nvk_min_cbuf_alignment(info), - .minStorageBufferOffsetAlignment = NVK_MIN_SSBO_ALIGNMENT, + .minStorageBufferOffsetAlignment = nvk_min_ssbo_alignment(instance), .minTexelOffset = -8, .maxTexelOffset = 7, .minTexelGatherOffset = -32, diff --git a/src/nouveau/vulkan/nvk_physical_device.h b/src/nouveau/vulkan/nvk_physical_device.h index b104b153870..06d4cc3bc83 100644 --- a/src/nouveau/vulkan/nvk_physical_device.h +++ b/src/nouveau/vulkan/nvk_physical_device.h @@ -39,6 +39,7 @@ struct nvk_physical_device { struct vk_physical_device vk; struct nv_device_info info; enum nvk_debug debug_flags; + bool ssbo_align_4b; struct nvkmd_pdev *nvkmd; diff --git a/src/nouveau/vulkan/nvk_private.h b/src/nouveau/vulkan/nvk_private.h index b7f4c0b56a0..cb9c948c090 100644 --- a/src/nouveau/vulkan/nvk_private.h +++ b/src/nouveau/vulkan/nvk_private.h @@ -15,7 +15,6 @@ #define NVK_MAX_DYNAMIC_BUFFERS 64 #define NVK_MAX_RTS 8 #define NVK_MAX_SAMPLES 8 -#define NVK_MIN_SSBO_ALIGNMENT 16 #define NVK_MIN_TEXEL_BUFFER_ALIGNMENT 16 #define NVK_MIN_UBO_ALIGNMENT 64 #define NVK_MAX_VIEWPORTS 16 diff --git a/src/nouveau/vulkan/nvk_shader.c b/src/nouveau/vulkan/nvk_shader.c index 8f7f781034b..cc9e12b0aff 100644 --- a/src/nouveau/vulkan/nvk_shader.c +++ b/src/nouveau/vulkan/nvk_shader.c @@ -7,6 +7,7 @@ #include "nvk_cmd_buffer.h" #include "nvk_descriptor_set_layout.h" #include "nvk_device.h" +#include "nvk_instance.h" #include "nvk_mme.h" #include "nvk_physical_device.h" #include "nvk_sampler.h" @@ -68,6 +69,7 @@ shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align) uint64_t nvk_physical_device_compiler_flags(const struct nvk_physical_device *pdev) { + const struct nvk_instance *instance = nvk_physical_device_instance(pdev); bool no_cbufs = pdev->debug_flags & NVK_DEBUG_NO_CBUF; bool use_edb_buffer_views = nvk_use_edb_buffer_views(pdev); uint64_t nak_flags = nak_debug_flags(pdev->nak); @@ -76,6 +78,7 @@ nvk_physical_device_compiler_flags(const struct nvk_physical_device *pdev) return ((uint64_t)no_cbufs << 12) | ((uint64_t)use_edb_buffer_views << 13) + | ((uint64_t)instance->ssbo_align_4b << 14) | (nak_flags << 48); } @@ -138,13 +141,14 @@ nvk_get_spirv_options(struct vk_physical_device *vk_pdev, { const struct nvk_physical_device *pdev = container_of(vk_pdev, struct nvk_physical_device, vk); + const struct nvk_instance *instance = nvk_physical_device_instance(pdev); return (struct spirv_to_nir_options) { .ssbo_addr_format = nvk_ssbo_addr_format(pdev, rs), .phys_ssbo_addr_format = nir_address_format_64bit_global, .ubo_addr_format = nvk_ubo_addr_format(pdev, rs), .shared_addr_format = nir_address_format_32bit_offset, - .min_ssbo_alignment = NVK_MIN_SSBO_ALIGNMENT, + .min_ssbo_alignment = nvk_min_ssbo_alignment(instance), .min_ubo_alignment = nvk_min_cbuf_alignment(&pdev->info), }; }