diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index 61a7586c28b..5651510a683 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -801,6 +801,7 @@ static const driOptionDescription tu_dri_options[] = { DRI_CONF_SECTION_MISCELLANEOUS DRI_CONF_DISABLE_CONSERVATIVE_LRZ(false) DRI_CONF_TU_DONT_RESERVE_DESCRIPTOR_SET(false) + DRI_CONF_TU_ALLOW_OOB_INDIRECT_UBO_LOADS(false) DRI_CONF_SECTION_END }; @@ -819,6 +820,8 @@ tu_init_dri_options(struct tu_instance *instance) !driQueryOptionb(&instance->dri_options, "disable_conservative_lrz"); instance->reserve_descriptor_set = !driQueryOptionb(&instance->dri_options, "tu_dont_reserve_descriptor_set"); + instance->allow_oob_indirect_ubo_loads = + driQueryOptionb(&instance->dri_options, "tu_allow_oob_indirect_ubo_loads"); } VKAPI_ATTR VkResult VKAPI_CALL diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index 0bbbbf60883..22d8d6fdd19 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -166,6 +166,14 @@ struct tu_instance * core, this is enabled by default. */ bool reserve_descriptor_set; + + /* Allow out of bounds UBO access by disabling lowering of UBO loads for + * indirect access, which rely on the UBO bounds specified in the shader, + * rather than the bound UBO size which isn't known until draw time. + * + * See: https://github.com/doitsujin/dxvk/issues/3861 + */ + bool allow_oob_indirect_ubo_loads; }; VK_DEFINE_HANDLE_CASTS(tu_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE) diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index 5b511a1734c..7abf5c2a343 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -312,6 +312,14 @@ lower_ssbo_ubo_intrinsic(struct tu_device *dev, nir_scalar scalar_idx = nir_scalar_resolved(intrin->src[buffer_src].ssa, 0); nir_def *descriptor_idx = nir_channel(b, intrin->src[buffer_src].ssa, 1); + if (intrin->intrinsic == nir_intrinsic_load_ubo && + dev->instance->allow_oob_indirect_ubo_loads) { + nir_scalar offset = nir_scalar_resolved(intrin->src[1].ssa, 0); + if (!nir_scalar_is_const(offset)) { + nir_intrinsic_set_range(intrin, ~0); + } + } + /* For isam, we need to use the appropriate descriptor if 16-bit storage is * enabled. Descriptor 0 is the 16-bit one, descriptor 1 is the 32-bit one. */ diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index e5a03cc7b47..6202f78ed3b 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -1327,4 +1327,16 @@ TODO: document the other workarounds.