radv: Advertise sparse features pre Polaris with perftest flag

RADV_PERFTEST=sparse is a new option to enable experimental
support for sparse features when they aren't enabled by default:

- gfx6 supports sparse, albeit with a reduced feature set
- gfx7 supports 3D images (with non-standard block shape)
  and unaligned mip sizes
- gfx8 supports the same feature set as gfx7

(Polaris behaves more stable than other gfx8, so we had
already enabled it by default on Polaris for a long time.)

We pass all dEQP-VK.*sparse* tests on gfx6-8 when running on
a single thread however it may cause hangs or failures
when executing the tests on multiple parallel jobs.

We plan to enable this by default when we deem it stable enough.
Until then, users can already test some games that use it.
Note, at the moment there are some unsolved problems in the
amdgpu kernel driver regarding sparse bindings on these GPUs.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38553>
This commit is contained in:
Timur Kristóf 2025-11-20 13:17:22 +01:00
parent f00abaa1d4
commit 4a76ed16d9
5 changed files with 33 additions and 18 deletions

View file

@ -1548,6 +1548,8 @@ RADV driver environment variables
enable wave64 for ray tracing shaders (GFX10-10.3)
``sam``
enable optimizations to move more driver internal objects to VRAM.
``sparse``
enable experimental sparse binding and sparse residency on GPUs where we don't support it by default (pre Polaris)
``transfer_queue``
enable experimental transfer queue support (GFX9+, not yet spec compliant)
``video_decode``

View file

@ -97,6 +97,7 @@ enum {
RADV_PERFTEST_VIDEO_ENCODE = 1u << 15,
RADV_PERFTEST_NO_GTT_SPILL = 1u << 16,
RADV_PERFTEST_HIC = 1u << 17,
RADV_PERFTEST_SPARSE = 1u << 18,
};
enum {

View file

@ -1072,8 +1072,7 @@ radv_get_image_format_properties(struct radv_physical_device *pdev, const VkPhys
}
if (info->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
/* Sparse textures are only supported on GFX8+. */
if (pdev->info.gfx_level < GFX8)
if (info->type == VK_IMAGE_TYPE_3D && !pdev->info.has_sparse_image_3d)
goto unsupported;
if (vk_format_get_plane_count(format) > 1 || info->type == VK_IMAGE_TYPE_1D ||

View file

@ -122,6 +122,7 @@ static const struct debug_control radv_perftest_options[] = {
{"video_encode", RADV_PERFTEST_VIDEO_ENCODE},
{"nogttspill", RADV_PERFTEST_NO_GTT_SPILL},
{"hic", RADV_PERFTEST_HIC},
{"sparse", RADV_PERFTEST_SPARSE},
{NULL, 0},
};

View file

@ -75,6 +75,15 @@ radv_taskmesh_enabled(const struct radv_physical_device *pdev)
pdev->info.has_gang_submit;
}
static bool
radv_sparse_enabled(const struct radv_physical_device *pdev)
{
const struct radv_instance *instance = radv_physical_device_instance(pdev);
return pdev->info.has_sparse ||
(instance->perftest_flags & RADV_PERFTEST_SPARSE);
}
bool
radv_transfer_queue_enabled(const struct radv_physical_device *pdev)
{
@ -854,6 +863,7 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
bool has_shader_image_float_minmax = pdev->info.gfx_level != GFX8 && pdev->info.gfx_level != GFX9 &&
pdev->info.gfx_level != GFX11 && pdev->info.gfx_level != GFX11_5;
bool has_fragment_shader_interlock = radv_has_pops(pdev);
const bool enable_sparse = radv_sparse_enabled(pdev);
*features = (struct vk_features){
/* Vulkan 1.0 */
@ -899,14 +909,14 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
.shaderFloat64 = true,
.shaderInt64 = true,
.shaderInt16 = true,
.sparseBinding = pdev->info.has_sparse,
.sparseResidencyBuffer = pdev->info.family >= CHIP_POLARIS10,
.sparseResidencyImage2D = pdev->info.family >= CHIP_POLARIS10,
.sparseResidencyImage3D = pdev->info.family >= CHIP_POLARIS10,
.sparseResidencyAliased = pdev->info.family >= CHIP_POLARIS10,
.sparseBinding = enable_sparse,
.sparseResidencyBuffer = enable_sparse,
.sparseResidencyImage2D = enable_sparse,
.sparseResidencyImage3D = enable_sparse && pdev->info.has_sparse_image_3d,
.sparseResidencyAliased = enable_sparse,
.variableMultisampleRate = true,
.shaderResourceMinLod = true,
.shaderResourceResidency = true,
.shaderResourceMinLod = enable_sparse,
.shaderResourceResidency = enable_sparse,
.inheritedQueries = true,
/* Vulkan 1.1 */
@ -1086,8 +1096,8 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
.shaderSharedFloat64AtomicAdd = false,
.shaderImageFloat32Atomics = true,
.shaderImageFloat32AtomicAdd = pdev->info.gfx_level >= GFX12 && !pdev->use_llvm,
.sparseImageFloat32Atomics = true,
.sparseImageFloat32AtomicAdd = pdev->info.gfx_level >= GFX12 && !pdev->use_llvm,
.sparseImageFloat32Atomics = enable_sparse,
.sparseImageFloat32AtomicAdd = enable_sparse && pdev->info.gfx_level >= GFX12 && !pdev->use_llvm,
/* VK_EXT_4444_formats */
.formatA4R4G4B4 = true,
@ -1095,7 +1105,7 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
/* VK_EXT_shader_image_atomic_int64 */
.shaderImageInt64Atomics = true,
.sparseImageInt64Atomics = true,
.sparseImageInt64Atomics = enable_sparse,
/* VK_EXT_mutable_descriptor_type */
.mutableDescriptorType = true,
@ -1159,7 +1169,7 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc
.shaderSharedFloat32AtomicMinMax = true,
.shaderSharedFloat64AtomicMinMax = true,
.shaderImageFloat32AtomicMinMax = has_shader_image_float_minmax,
.sparseImageFloat32AtomicMinMax = has_shader_image_float_minmax,
.sparseImageFloat32AtomicMinMax = enable_sparse && has_shader_image_float_minmax,
#ifdef RADV_USE_WSI_PLATFORM
/* VK_KHR_present_id */
@ -1565,6 +1575,7 @@ radv_get_physical_device_properties(struct radv_physical_device *pdev)
}
const bool has_fp16 = radv_shader_fp16_enabled(pdev);
const bool enable_sparse = radv_sparse_enabled(pdev);
VkShaderStageFlags taskmesh_stages =
radv_taskmesh_enabled(pdev) ? VK_SHADER_STAGE_MESH_BIT_EXT | VK_SHADER_STAGE_TASK_BIT_EXT : 0;
@ -1604,7 +1615,7 @@ radv_get_physical_device_properties(struct radv_physical_device *pdev)
.maxMemoryAllocationCount = UINT32_MAX,
.maxSamplerAllocationCount = 64 * 1024,
.bufferImageGranularity = 1,
.sparseAddressSpaceSize = pdev->info.has_sparse ? pdev->info.virtual_address_max : 0,
.sparseAddressSpaceSize = enable_sparse ? pdev->info.virtual_address_max : 0,
.maxBoundDescriptorSets = MAX_SETS,
.maxPerStageDescriptorSamplers = max_descriptor_set_size,
.maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
@ -1698,9 +1709,10 @@ radv_get_physical_device_properties(struct radv_physical_device *pdev)
.optimalBufferCopyOffsetAlignment = 1,
.optimalBufferCopyRowPitchAlignment = 1,
.nonCoherentAtomSize = 64,
.sparseResidencyNonResidentStrict = pdev->info.family >= CHIP_POLARIS10,
.sparseResidencyStandard2DBlockShape = pdev->info.family >= CHIP_POLARIS10,
.sparseResidencyStandard3DBlockShape = pdev->info.gfx_level >= GFX9,
.sparseResidencyNonResidentStrict = enable_sparse,
.sparseResidencyAlignedMipSize = enable_sparse && !pdev->info.has_sparse_unaligned_mip_size,
.sparseResidencyStandard2DBlockShape = enable_sparse,
.sparseResidencyStandard3DBlockShape = enable_sparse && pdev->info.has_sparse_image_standard_3d,
/* Vulkan 1.1 */
.driverID = VK_DRIVER_ID_MESA_RADV,
@ -2129,7 +2141,7 @@ radv_get_physical_device_properties(struct radv_physical_device *pdev)
.deviceGeneratedCommandsMultiDrawIndirectCount = true,
/* VK_KHR_maintenance9 */
.image2DViewOf3DSparse = pdev->info.gfx_level >= GFX8,
.image2DViewOf3DSparse = enable_sparse && pdev->info.has_sparse_image_3d,
.defaultVertexAttributeValue = VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_ZERO_ZERO_ZERO_ZERO_KHR,
/* VK_NV_cooperative_matrix2 */