diff --git a/docs/envvars.rst b/docs/envvars.rst index beec1a7ceb7..a88574b9ce0 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -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`` diff --git a/src/amd/vulkan/radv_debug.h b/src/amd/vulkan/radv_debug.h index cd0c95c7b3e..bf235e4d076 100644 --- a/src/amd/vulkan/radv_debug.h +++ b/src/amd/vulkan/radv_debug.h @@ -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 { diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index dd6985365ee..eb3f92790f3 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -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 || diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c index a7671487fcc..f889f4dd4df 100644 --- a/src/amd/vulkan/radv_instance.c +++ b/src/amd/vulkan/radv_instance.c @@ -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}, }; diff --git a/src/amd/vulkan/radv_physical_device.c b/src/amd/vulkan/radv_physical_device.c index 02c4b4513b7..d7dde4d2634 100644 --- a/src/amd/vulkan/radv_physical_device.c +++ b/src/amd/vulkan/radv_physical_device.c @@ -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 */