From 0067f8992002b44bf75f98fae43886c5a6227075 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Thu, 30 Jul 2020 02:49:33 +0200 Subject: [PATCH] radv: Override the uniform buffer offset alignment for World War Z. Game does the equivalent of a ALIGN(..., minUniformBufferOffsetAlignment >> 4) which breaks when said alignment is <16 with a SIGFPE. CC: Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_device.c | 18 +++++++++++++++++- src/util/00-mesa-defaults.conf | 4 ++++ src/util/driconf.h | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 0f40db2cceb..dda535d5538 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -615,6 +615,7 @@ DRI_CONF_BEGIN DRI_CONF_RADV_REPORT_LLVM9_VERSION_STRING("false") DRI_CONF_RADV_ENABLE_MRT_OUTPUT_NAN_FIXUP("false") DRI_CONF_RADV_NO_DYNAMIC_BOUNDS("false") + DRI_CONF_RADV_OVERRIDE_UNIFORM_OFFSET_ALIGNMENT(0) DRI_CONF_SECTION_END DRI_CONF_SECTION_DEBUG @@ -1445,6 +1446,21 @@ radv_max_descriptor_set_size() 64 /* storage image */); } +static uint32_t +radv_uniform_buffer_offset_alignment(const struct radv_physical_device *pdevice) +{ + uint32_t uniform_offset_alignment = driQueryOptioni(&pdevice->instance->dri_options, + "radv_override_uniform_offset_alignment"); + if (!util_is_power_of_two_or_zero(uniform_offset_alignment)) { + fprintf(stderr, "ERROR: invalid radv_override_uniform_offset_alignment setting %d:" + "not a power of two\n", uniform_offset_alignment); + uniform_offset_alignment = 0; + } + + /* Take at least the hardware limit. */ + return MAX2(uniform_offset_alignment, 4); +} + void radv_GetPhysicalDeviceProperties( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties) @@ -1527,7 +1543,7 @@ void radv_GetPhysicalDeviceProperties( .viewportSubPixelBits = 8, .minMemoryMapAlignment = 4096, /* A page */ .minTexelBufferOffsetAlignment = 4, - .minUniformBufferOffsetAlignment = 4, + .minUniformBufferOffsetAlignment = radv_uniform_buffer_offset_alignment(pdevice), .minStorageBufferOffsetAlignment = 4, .minTexelOffset = -32, .maxTexelOffset = 31, diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index 2a1dd8f26fe..5cd65ccf18d 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -733,5 +733,9 @@ TODO: document the other workarounds. + + + diff --git a/src/util/driconf.h b/src/util/driconf.h index c922e94b9f9..d7c734464cc 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -508,4 +508,8 @@ DRI_CONF_OPT_BEGIN_B(radv_no_dynamic_bounds, def) \ DRI_CONF_DESC("Disabling bounds checking for dynamic buffer descriptors") \ DRI_CONF_OPT_END +#define DRI_CONF_RADV_OVERRIDE_UNIFORM_OFFSET_ALIGNMENT(def) \ +DRI_CONF_OPT_BEGIN_V(radv_override_uniform_offset_alignment, int, def, "0:128") \ + DRI_CONF_DESC("Override the minUniformBufferOffsetAlignment exposed to the application. (0 = default)") \ +DRI_CONF_OPT_END #endif -- 2.30.2