diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index 408e9b4dc9f..d2f43494cd7 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -342,7 +342,7 @@ if with_radv_tests inc_util, include_directories('.'), ], - link_with : [ libvulkan_radeon ], + link_with : [ libamd_common, libvulkan_radeon, libamdgpu_noop_drm_shim ], dependencies : [dep_llvm, dep_thread, idep_gtest, idep_nir, idep_mesautil, idep_vulkan_util_headers], ), suite : ['compiler', 'nir'], diff --git a/src/amd/vulkan/tests/helpers.cpp b/src/amd/vulkan/tests/helpers.cpp index 11ce9f0fc6b..0d81e15d7fb 100644 --- a/src/amd/vulkan/tests/helpers.cpp +++ b/src/amd/vulkan/tests/helpers.cpp @@ -7,6 +7,8 @@ #include "helpers.h" #include "util/macros.h" +#include "drm-shim/amdgpu_noop_drm_shim.h" + extern "C" { PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName); } @@ -250,3 +252,18 @@ radv_test::get_pipeline_key(uint32_t code_size, const uint32_t *code, VkPipeline DestroyPipelineLayout(device, pipeline_layout, NULL); DestroyShaderModule(device, shader_module, NULL); } + +void +radv_test::get_global_pipeline_key(enum radeon_family family, VkPipelineBinaryKeyKHR *pipeline_key) +{ + VkResult result; + + drm_shim_amdgpu_select_device(ac_get_family_name(family)); + + create_device(); + + result = GetPipelineKeyKHR(device, NULL, pipeline_key); + assert(result == VK_SUCCESS); + + destroy_device(); +} diff --git a/src/amd/vulkan/tests/helpers.h b/src/amd/vulkan/tests/helpers.h index c61b31c71d1..fbbb3cbeebf 100644 --- a/src/amd/vulkan/tests/helpers.h +++ b/src/amd/vulkan/tests/helpers.h @@ -15,6 +15,8 @@ #include "util/os_misc.h" +#include "common/amd_family.h" + #define FUNCTION_LIST \ ITEM(CreateInstance) \ ITEM(DestroyInstance) \ @@ -53,6 +55,8 @@ public: void get_pipeline_key(uint32_t code_size, const uint32_t *code, VkPipelineBinaryKeyKHR *pipeline_key, VkPipelineCreateFlags flags = 0); + void get_global_pipeline_key(enum radeon_family family, VkPipelineBinaryKeyKHR *pipeline_key); + uint64_t get_pipeline_hash(VkShaderStageFlags stage); void add_envvar(std::string name, std::string value) diff --git a/src/amd/vulkan/tests/misc.cpp b/src/amd/vulkan/tests/misc.cpp index 019eed09f27..2d1cd93dba7 100644 --- a/src/amd/vulkan/tests/misc.cpp +++ b/src/amd/vulkan/tests/misc.cpp @@ -113,3 +113,41 @@ TEST_F(misc, pipeline_key_rgp_fossilize) destroy_device(); } + +/** + * This test verifies the compatibility between global pipeline keys. These keys are computed from + * the device cache hash which is used to share shader binaries between different compatible GPUs. + */ +TEST_F(misc, global_pipeline_key_compat) +{ + /* RDNA2 keys */ + VkPipelineBinaryKeyKHR vangogh, rembrandt, navi21; + get_global_pipeline_key(CHIP_VANGOGH, &vangogh); + get_global_pipeline_key(CHIP_REMBRANDT, &rembrandt); + get_global_pipeline_key(CHIP_NAVI21, &navi21); + + /* Verify that global keys between VANGOGH and REMBRANDT are compatible. */ + EXPECT_EQ(vangogh.keySize, rembrandt.keySize); + EXPECT_FALSE(memcmp(vangogh.key, rembrandt.key, vangogh.keySize)); + + /* Verify that global keys between VANGOGH and NAVI21 aren't compatible. */ + EXPECT_EQ(vangogh.keySize, navi21.keySize); + EXPECT_TRUE(memcmp(vangogh.key, navi21.key, vangogh.keySize)); + + /* RDNA3 keys */ + VkPipelineBinaryKeyKHR phoenix, phoenix2, navi33, navi31; + get_global_pipeline_key(CHIP_PHOENIX, &phoenix); + get_global_pipeline_key(CHIP_PHOENIX2, &phoenix2); + get_global_pipeline_key(CHIP_NAVI33, &navi33); + get_global_pipeline_key(CHIP_NAVI31, &navi31); + + /* Verify that global keys between PHOENIX, PHOENIX2 and NAVI33 are compatible. */ + EXPECT_EQ(phoenix.keySize, phoenix2.keySize); + EXPECT_EQ(phoenix2.keySize, navi33.keySize); + EXPECT_FALSE(memcmp(phoenix.key, phoenix2.key, phoenix.keySize)); + EXPECT_FALSE(memcmp(phoenix2.key, navi33.key, phoenix2.keySize)); + + /* Verify that global keys between NAVI33 and NAVI31 aren't compatible. */ + EXPECT_EQ(navi33.keySize, navi31.keySize); + EXPECT_TRUE(memcmp(navi33.key, navi31.key, navi33.keySize)); +}