mirror of
https://github.com/johndoe6345789/MetalOS.git
synced 2026-05-01 00:56:03 +00:00
253 lines
7.3 KiB
C++
253 lines
7.3 KiB
C++
/*
|
|
* Copyright © 2025 Valve Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "helpers.h"
|
|
#include "util/macros.h"
|
|
|
|
extern "C" {
|
|
PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
|
|
}
|
|
|
|
radv_test::radv_test()
|
|
{
|
|
}
|
|
|
|
radv_test::~radv_test()
|
|
{
|
|
assert(envvars.size() == 0);
|
|
}
|
|
|
|
void
|
|
radv_test::create_device()
|
|
{
|
|
VkResult result;
|
|
|
|
/* Create instance. */
|
|
VkApplicationInfo app_info = {
|
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
|
.pApplicationName = "radv_tests",
|
|
.apiVersion = VK_API_VERSION_1_4,
|
|
};
|
|
|
|
VkInstanceCreateInfo instance_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
|
.pApplicationInfo = &app_info,
|
|
};
|
|
|
|
result = ((PFN_vkCreateInstance)vk_icdGetInstanceProcAddr(NULL, "vkCreateInstance"))(&instance_create_info, NULL,
|
|
&instance);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
#define ITEM(n) n = (PFN_vk##n)vk_icdGetInstanceProcAddr(instance, "vk" #n);
|
|
FUNCTION_LIST
|
|
#undef ITEM
|
|
|
|
/* Get physical device. */
|
|
uint32_t device_count = 1;
|
|
|
|
result = EnumeratePhysicalDevices(instance, &device_count, &physical_device);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
/* Create logical device. */
|
|
static const char *extensions[] = {"VK_KHR_pipeline_executable_properties"};
|
|
|
|
VkDeviceCreateInfo device_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
|
.enabledExtensionCount = ARRAY_SIZE(extensions),
|
|
.ppEnabledExtensionNames = extensions,
|
|
};
|
|
|
|
result = CreateDevice(physical_device, &device_create_info, NULL, &device);
|
|
assert(result == VK_SUCCESS);
|
|
}
|
|
|
|
void
|
|
radv_test::destroy_device()
|
|
{
|
|
unset_envvars();
|
|
|
|
DestroyDevice(device, NULL);
|
|
DestroyInstance(instance, NULL);
|
|
}
|
|
|
|
void
|
|
radv_test::get_physical_device_properties2(VkPhysicalDeviceProperties2 *pdev_props)
|
|
{
|
|
GetPhysicalDeviceProperties2(physical_device, pdev_props);
|
|
}
|
|
|
|
void
|
|
radv_test::get_physical_device_format_properties2(VkFormat format, VkFormatProperties2 *format_props)
|
|
{
|
|
GetPhysicalDeviceFormatProperties2(physical_device, format, format_props);
|
|
}
|
|
|
|
bool
|
|
radv_test::is_dedicated_sparse_queue_enabled()
|
|
{
|
|
bool found_dedicated_sparse_queue = false;
|
|
uint32_t num_queue_family_props = 0;
|
|
|
|
GetPhysicalDeviceQueueFamilyProperties2(physical_device, &num_queue_family_props, NULL);
|
|
if (num_queue_family_props > 0) {
|
|
VkQueueFamilyProperties2 *queue_family_props = NULL;
|
|
|
|
queue_family_props = (VkQueueFamilyProperties2 *)calloc(num_queue_family_props, sizeof(*queue_family_props));
|
|
assert(queue_family_props);
|
|
|
|
GetPhysicalDeviceQueueFamilyProperties2(physical_device, &num_queue_family_props, queue_family_props);
|
|
|
|
for (uint32_t i = 0; i < num_queue_family_props; i++) {
|
|
VkQueueFamilyProperties2 *queue_family_prop = &queue_family_props[i];
|
|
if (queue_family_prop->queueFamilyProperties.queueFlags == VK_QUEUE_SPARSE_BINDING_BIT)
|
|
found_dedicated_sparse_queue = true;
|
|
}
|
|
|
|
free(queue_family_props);
|
|
}
|
|
|
|
return found_dedicated_sparse_queue;
|
|
}
|
|
|
|
void
|
|
radv_test::create_compute_pipeline(uint32_t code_size, const uint32_t *code, VkPipelineCreateFlags flags)
|
|
{
|
|
VkResult result;
|
|
|
|
VkShaderModuleCreateInfo shader_module_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
|
.codeSize = code_size,
|
|
.pCode = code,
|
|
};
|
|
VkShaderModule shader_module;
|
|
|
|
result = CreateShaderModule(device, &shader_module_create_info, NULL, &shader_module);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
};
|
|
|
|
result = CreatePipelineLayout(device, &pipeline_layout_info, NULL, &pipeline_layout);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
VkPipelineShaderStageCreateInfo stage_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
.module = shader_module,
|
|
.pName = "main",
|
|
};
|
|
|
|
VkComputePipelineCreateInfo pipeline_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
|
.flags = flags,
|
|
.stage = stage_create_info,
|
|
.layout = pipeline_layout,
|
|
};
|
|
|
|
result = CreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &pipeline);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
DestroyShaderModule(device, shader_module, NULL);
|
|
}
|
|
|
|
void
|
|
radv_test::destroy_pipeline()
|
|
{
|
|
DestroyPipelineLayout(device, pipeline_layout, NULL);
|
|
DestroyPipeline(device, pipeline, NULL);
|
|
}
|
|
|
|
uint64_t
|
|
radv_test::get_pipeline_hash(VkShaderStageFlags stage)
|
|
{
|
|
VkResult result;
|
|
|
|
uint32_t executable_count = 16;
|
|
VkPipelineExecutablePropertiesKHR executables[16];
|
|
VkPipelineInfoKHR pipeline_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,
|
|
.pipeline = pipeline,
|
|
};
|
|
|
|
result = GetPipelineExecutablePropertiesKHR(device, &pipeline_info, &executable_count, executables);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
uint32_t executable = 0;
|
|
for (; executable < executable_count; executable++) {
|
|
if (executables[executable].stages == stage)
|
|
break;
|
|
}
|
|
assert(executable != executable_count);
|
|
|
|
uint32_t stat_count = 32;
|
|
VkPipelineExecutableStatisticKHR stats[32];
|
|
VkPipelineExecutableInfoKHR exec_info{
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR,
|
|
.pipeline = pipeline,
|
|
.executableIndex = executable,
|
|
};
|
|
|
|
result = GetPipelineExecutableStatisticsKHR(device, &exec_info, &stat_count, stats);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
for (uint32_t i = 0; i < stat_count; i++) {
|
|
if (!strcmp(stats[i].name, "Driver pipeline hash"))
|
|
return stats[i].value.u64;
|
|
}
|
|
|
|
UNREACHABLE("Driver pipeline hash not found");
|
|
}
|
|
|
|
void
|
|
radv_test::get_pipeline_key(uint32_t code_size, const uint32_t *code, VkPipelineBinaryKeyKHR *pipeline_key,
|
|
VkPipelineCreateFlags flags)
|
|
{
|
|
VkResult result;
|
|
|
|
VkShaderModuleCreateInfo shader_module_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
|
.codeSize = code_size,
|
|
.pCode = code,
|
|
};
|
|
VkShaderModule shader_module;
|
|
|
|
result = CreateShaderModule(device, &shader_module_create_info, NULL, &shader_module);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
};
|
|
|
|
result = CreatePipelineLayout(device, &pipeline_layout_info, NULL, &pipeline_layout);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
VkPipelineShaderStageCreateInfo stage_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
|
.module = shader_module,
|
|
.pName = "main",
|
|
};
|
|
|
|
VkComputePipelineCreateInfo compute_pipeline_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
|
.flags = flags,
|
|
.stage = stage_create_info,
|
|
.layout = pipeline_layout,
|
|
};
|
|
|
|
VkPipelineCreateInfoKHR pipeline_create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_INFO_KHR,
|
|
.pNext = &compute_pipeline_create_info,
|
|
};
|
|
|
|
result = GetPipelineKeyKHR(device, &pipeline_create_info, pipeline_key);
|
|
assert(result == VK_SUCCESS);
|
|
|
|
DestroyPipelineLayout(device, pipeline_layout, NULL);
|
|
DestroyShaderModule(device, shader_module, NULL);
|
|
}
|