mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
tests/shader-runner: Move struct vulkan_test_context to vulkan_utils.h.
This commit is contained in:
parent
fc65170521
commit
ce83628882
Notes:
Henri Verbeet
2024-10-08 22:10:46 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/905
@ -284,7 +284,8 @@ vkd3d_test_headers = \
|
|||||||
tests/dxcompiler.h \
|
tests/dxcompiler.h \
|
||||||
tests/shader_runner.h \
|
tests/shader_runner.h \
|
||||||
tests/utils.h \
|
tests/utils.h \
|
||||||
tests/vulkan_procs.h
|
tests/vulkan_procs.h \
|
||||||
|
tests/vulkan_utils.h
|
||||||
|
|
||||||
vkd3d_demos = \
|
vkd3d_demos = \
|
||||||
demos/vkd3d-gears \
|
demos/vkd3d-gears \
|
||||||
|
@ -23,10 +23,10 @@
|
|||||||
#define VK_NO_PROTOTYPES
|
#define VK_NO_PROTOTYPES
|
||||||
#define VKD3D_TEST_NO_DEFS
|
#define VKD3D_TEST_NO_DEFS
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "vulkan/vulkan.h"
|
|
||||||
#include "vkd3d.h"
|
#include "vkd3d.h"
|
||||||
#include "vkd3d_d3dcompiler.h"
|
#include "vkd3d_d3dcompiler.h"
|
||||||
#include "shader_runner.h"
|
#include "shader_runner.h"
|
||||||
|
#include "vulkan_utils.h"
|
||||||
#include "vkd3d_test.h"
|
#include "vkd3d_test.h"
|
||||||
|
|
||||||
struct vulkan_resource
|
struct vulkan_resource
|
||||||
@ -47,27 +47,6 @@ static struct vulkan_resource *vulkan_resource(struct resource *r)
|
|||||||
return CONTAINING_RECORD(r, struct vulkan_resource, r);
|
return CONTAINING_RECORD(r, struct vulkan_resource, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_VK_PFN(name) PFN_##name name;
|
|
||||||
|
|
||||||
DECLARE_VK_PFN(vkGetInstanceProcAddr)
|
|
||||||
|
|
||||||
struct vulkan_test_context
|
|
||||||
{
|
|
||||||
VkInstance instance;
|
|
||||||
VkPhysicalDevice phys_device;
|
|
||||||
VkDevice device;
|
|
||||||
VkQueue queue;
|
|
||||||
VkCommandPool command_pool;
|
|
||||||
VkCommandBuffer cmd_buffer;
|
|
||||||
VkDescriptorPool descriptor_pool;
|
|
||||||
|
|
||||||
DECLARE_VK_PFN(vkCreateInstance);
|
|
||||||
DECLARE_VK_PFN(vkEnumerateInstanceExtensionProperties);
|
|
||||||
#define VK_INSTANCE_PFN DECLARE_VK_PFN
|
|
||||||
#define VK_DEVICE_PFN DECLARE_VK_PFN
|
|
||||||
#include "vulkan_procs.h"
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vulkan_shader_runner
|
struct vulkan_shader_runner
|
||||||
{
|
{
|
||||||
struct shader_runner r;
|
struct shader_runner r;
|
||||||
@ -85,12 +64,6 @@ struct vulkan_shader_runner
|
|||||||
} samplers[MAX_SAMPLERS];
|
} samplers[MAX_SAMPLERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct extension_list
|
|
||||||
{
|
|
||||||
const char **names;
|
|
||||||
size_t count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct physical_device_info
|
struct physical_device_info
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceFeatures2 features2;
|
VkPhysicalDeviceFeatures2 features2;
|
||||||
@ -103,8 +76,6 @@ static struct vulkan_shader_runner *vulkan_shader_runner(struct shader_runner *r
|
|||||||
return CONTAINING_RECORD(r, struct vulkan_shader_runner, r);
|
return CONTAINING_RECORD(r, struct vulkan_shader_runner, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VK_CALL(f) (context->f)
|
|
||||||
|
|
||||||
static void begin_command_buffer(const struct vulkan_test_context *context)
|
static void begin_command_buffer(const struct vulkan_test_context *context)
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo buffer_begin_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
|
VkCommandBufferBeginInfo buffer_begin_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
|
||||||
@ -1559,68 +1530,8 @@ static const struct shader_runner_ops vulkan_runner_ops =
|
|||||||
.release_readback = vulkan_runner_release_readback,
|
.release_readback = vulkan_runner_release_readback,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool get_graphics_queue_index(const struct vulkan_test_context *context, uint32_t *index)
|
static bool check_device_extensions(struct vulkan_shader_runner *runner,
|
||||||
{
|
struct vulkan_extension_list *enabled_extensions)
|
||||||
VkQueueFamilyProperties *queue_properties;
|
|
||||||
uint32_t count, i;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(context->phys_device, &count, NULL));
|
|
||||||
queue_properties = malloc(count * sizeof(*queue_properties));
|
|
||||||
VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(context->phys_device, &count, queue_properties));
|
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
||||||
{
|
|
||||||
free(queue_properties);
|
|
||||||
*index = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(queue_properties);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool has_extension(const VkExtensionProperties *extensions, uint32_t count, const char *extension_name)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
if (!strcmp(extensions[i].extensionName, extension_name))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_instance_extensions(const struct vulkan_test_context *context,
|
|
||||||
const char **instance_extensions, size_t instance_extension_count,
|
|
||||||
struct extension_list *enabled_extensions)
|
|
||||||
{
|
|
||||||
VkExtensionProperties *extensions;
|
|
||||||
uint32_t count, i;
|
|
||||||
|
|
||||||
enabled_extensions->names = calloc(instance_extension_count, sizeof(*enabled_extensions->names));
|
|
||||||
enabled_extensions->count = 0;
|
|
||||||
|
|
||||||
VK_CALL(vkEnumerateInstanceExtensionProperties(NULL, &count, NULL));
|
|
||||||
extensions = calloc(count, sizeof(*extensions));
|
|
||||||
VK_CALL(vkEnumerateInstanceExtensionProperties(NULL, &count, extensions));
|
|
||||||
|
|
||||||
for (i = 0; i < instance_extension_count; ++i)
|
|
||||||
{
|
|
||||||
const char *name = instance_extensions[i];
|
|
||||||
|
|
||||||
if (has_extension(extensions, count, name))
|
|
||||||
enabled_extensions->names[enabled_extensions->count++] = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool check_device_extensions(struct vulkan_shader_runner *runner, struct extension_list *enabled_extensions)
|
|
||||||
{
|
{
|
||||||
const struct vulkan_test_context *context = &runner->context;
|
const struct vulkan_test_context *context = &runner->context;
|
||||||
VkPhysicalDevice phys_device = context->phys_device;
|
VkPhysicalDevice phys_device = context->phys_device;
|
||||||
@ -1651,7 +1562,7 @@ static bool check_device_extensions(struct vulkan_shader_runner *runner, struct
|
|||||||
{
|
{
|
||||||
const char *name = device_extensions[i].name;
|
const char *name = device_extensions[i].name;
|
||||||
|
|
||||||
if (has_extension(extensions, count, name))
|
if (vk_extension_properties_contain(extensions, count, name))
|
||||||
{
|
{
|
||||||
enabled_extensions->names[enabled_extensions->count++] = name;
|
enabled_extensions->names[enabled_extensions->count++] = name;
|
||||||
if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME))
|
if (!strcmp(name, VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME))
|
||||||
@ -1713,132 +1624,6 @@ static uint32_t get_format_support(const struct vulkan_test_context *context, en
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vulkan_test_context_init_instance(struct vulkan_test_context *context,
|
|
||||||
const char **instance_extensions, size_t instance_extension_count)
|
|
||||||
{
|
|
||||||
VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
|
|
||||||
struct extension_list enabled_extensions;
|
|
||||||
void *libvulkan;
|
|
||||||
uint32_t count;
|
|
||||||
VkResult vr;
|
|
||||||
|
|
||||||
memset(context, 0, sizeof(*context));
|
|
||||||
|
|
||||||
if (!(libvulkan = vkd3d_dlopen(SONAME_LIBVULKAN)))
|
|
||||||
{
|
|
||||||
skip("Failed to load %s: %s.\n", SONAME_LIBVULKAN, vkd3d_dlerror());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
vkGetInstanceProcAddr = vkd3d_dlsym(libvulkan, "vkGetInstanceProcAddr");
|
|
||||||
|
|
||||||
context->vkCreateInstance = (void *)vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
|
||||||
context->vkEnumerateInstanceExtensionProperties = (void *)vkGetInstanceProcAddr(NULL,
|
|
||||||
"vkEnumerateInstanceExtensionProperties");
|
|
||||||
|
|
||||||
check_instance_extensions(context, instance_extensions, instance_extension_count, &enabled_extensions);
|
|
||||||
instance_desc.ppEnabledExtensionNames = enabled_extensions.names;
|
|
||||||
instance_desc.enabledExtensionCount = enabled_extensions.count;
|
|
||||||
vr = VK_CALL(vkCreateInstance(&instance_desc, NULL, &context->instance));
|
|
||||||
free(enabled_extensions.names);
|
|
||||||
if (vr < 0)
|
|
||||||
{
|
|
||||||
skip("Failed to create a Vulkan instance, vr %d.\n", vr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VK_INSTANCE_PFN(name) context->name = (void *)vkGetInstanceProcAddr(context->instance, #name);
|
|
||||||
#include "vulkan_procs.h"
|
|
||||||
|
|
||||||
count = 1;
|
|
||||||
if ((vr = VK_CALL(vkEnumeratePhysicalDevices(context->instance, &count, &context->phys_device))) < 0)
|
|
||||||
{
|
|
||||||
skip("Failed to enumerate physical devices, vr %d.\n", vr);
|
|
||||||
goto out_destroy_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!count)
|
|
||||||
{
|
|
||||||
skip("No Vulkan devices are available.\n");
|
|
||||||
goto out_destroy_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
out_destroy_instance:
|
|
||||||
VK_CALL(vkDestroyInstance(context->instance, NULL));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vulkan_test_context_init_device(struct vulkan_test_context *context,
|
|
||||||
const VkDeviceCreateInfo *device_desc, uint32_t queue_index, uint32_t max_resource_count,
|
|
||||||
uint32_t max_sampler_count)
|
|
||||||
{
|
|
||||||
VkDescriptorPoolCreateInfo descriptor_pool_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
|
|
||||||
VkCommandBufferAllocateInfo cmd_buffer_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
|
|
||||||
VkCommandPoolCreateInfo command_pool_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
|
|
||||||
VkDescriptorPoolSize descriptor_pool_sizes[6];
|
|
||||||
VkDevice device;
|
|
||||||
VkResult vr;
|
|
||||||
|
|
||||||
vr = VK_CALL(vkCreateDevice(context->phys_device, device_desc, NULL, &device));
|
|
||||||
if (vr)
|
|
||||||
{
|
|
||||||
skip("Failed to create device, vr %d.\n", vr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
context->device = device;
|
|
||||||
|
|
||||||
#define VK_DEVICE_PFN(name) context->name = (void *)VK_CALL(vkGetDeviceProcAddr(device, #name));
|
|
||||||
#include "vulkan_procs.h"
|
|
||||||
|
|
||||||
VK_CALL(vkGetDeviceQueue(device, queue_index, 0, &context->queue));
|
|
||||||
|
|
||||||
command_pool_desc.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
||||||
command_pool_desc.queueFamilyIndex = queue_index;
|
|
||||||
|
|
||||||
VK_CALL(vkCreateCommandPool(device, &command_pool_desc, NULL, &context->command_pool));
|
|
||||||
|
|
||||||
cmd_buffer_desc.commandPool = context->command_pool;
|
|
||||||
cmd_buffer_desc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
cmd_buffer_desc.commandBufferCount = 1;
|
|
||||||
|
|
||||||
VK_CALL(vkAllocateCommandBuffers(device, &cmd_buffer_desc, &context->cmd_buffer));
|
|
||||||
|
|
||||||
assert(max_resource_count);
|
|
||||||
|
|
||||||
descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
|
||||||
descriptor_pool_sizes[0].descriptorCount = max_resource_count;
|
|
||||||
descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
|
||||||
descriptor_pool_sizes[1].descriptorCount = max_resource_count;
|
|
||||||
descriptor_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
descriptor_pool_sizes[2].descriptorCount = max_resource_count;
|
|
||||||
descriptor_pool_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
|
|
||||||
descriptor_pool_sizes[3].descriptorCount = max_resource_count;
|
|
||||||
descriptor_pool_sizes[4].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
|
||||||
descriptor_pool_sizes[4].descriptorCount = max_resource_count;
|
|
||||||
descriptor_pool_sizes[5].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
|
||||||
descriptor_pool_sizes[5].descriptorCount = max_sampler_count;
|
|
||||||
|
|
||||||
descriptor_pool_desc.maxSets = 1;
|
|
||||||
descriptor_pool_desc.poolSizeCount = ARRAY_SIZE(descriptor_pool_sizes) - !max_sampler_count;
|
|
||||||
descriptor_pool_desc.pPoolSizes = descriptor_pool_sizes;
|
|
||||||
|
|
||||||
VK_CALL(vkCreateDescriptorPool(device, &descriptor_pool_desc, NULL, &context->descriptor_pool));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vulkan_test_context_destroy(const struct vulkan_test_context *context)
|
|
||||||
{
|
|
||||||
VkDevice device = context->device;
|
|
||||||
|
|
||||||
VK_CALL(vkDestroyDescriptorPool(device, context->descriptor_pool, NULL));
|
|
||||||
VK_CALL(vkFreeCommandBuffers(device, context->command_pool, 1, &context->cmd_buffer));
|
|
||||||
VK_CALL(vkDestroyCommandPool(device, context->command_pool, NULL));
|
|
||||||
VK_CALL(vkDestroyDevice(device, NULL));
|
|
||||||
VK_CALL(vkDestroyInstance(context->instance, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote_to_helper_invocation_features;
|
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote_to_helper_invocation_features;
|
||||||
@ -1846,8 +1631,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
|||||||
VkDeviceCreateInfo device_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
|
VkDeviceCreateInfo device_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
|
||||||
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT interlock_features;
|
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT interlock_features;
|
||||||
struct vulkan_test_context *context = &runner->context;
|
struct vulkan_test_context *context = &runner->context;
|
||||||
|
struct vulkan_extension_list enabled_extensions;
|
||||||
const VkPhysicalDeviceFeatures *ret_features;
|
const VkPhysicalDeviceFeatures *ret_features;
|
||||||
struct extension_list enabled_extensions;
|
|
||||||
static const float queue_priority = 1.0f;
|
static const float queue_priority = 1.0f;
|
||||||
struct physical_device_info device_info;
|
struct physical_device_info device_info;
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures features;
|
||||||
@ -1884,7 +1669,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
|||||||
if (!vulkan_test_context_init_instance(context, instance_extensions, ARRAY_SIZE(instance_extensions)))
|
if (!vulkan_test_context_init_instance(context, instance_extensions, ARRAY_SIZE(instance_extensions)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!get_graphics_queue_index(context, &graphics_index))
|
if (!get_vulkan_queue_index(context, VK_QUEUE_GRAPHICS_BIT, &graphics_index))
|
||||||
{
|
{
|
||||||
skip("The selected Vulkan device does not support graphics operations.\n");
|
skip("The selected Vulkan device does not support graphics operations.\n");
|
||||||
goto out_destroy_context;
|
goto out_destroy_context;
|
||||||
|
249
tests/vulkan_utils.h
Normal file
249
tests/vulkan_utils.h
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2022 Zebediah Figura for CodeWeavers
|
||||||
|
* Copyright 2024 Conor McCarthy for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VKD3D_VULKAN_UTILS_H
|
||||||
|
#define __VKD3D_VULKAN_UTILS_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "vulkan/vulkan.h"
|
||||||
|
#include "vkd3d_test.h"
|
||||||
|
|
||||||
|
/* The helpers in this file are not part of utils.h because vkd3d_api.c
|
||||||
|
* needs its own Vulkan helpers specific to API tests. */
|
||||||
|
|
||||||
|
#define DECLARE_VK_PFN(name) PFN_##name name;
|
||||||
|
|
||||||
|
struct vulkan_test_context
|
||||||
|
{
|
||||||
|
VkInstance instance;
|
||||||
|
VkPhysicalDevice phys_device;
|
||||||
|
VkDevice device;
|
||||||
|
VkQueue queue;
|
||||||
|
VkCommandPool command_pool;
|
||||||
|
VkCommandBuffer cmd_buffer;
|
||||||
|
VkDescriptorPool descriptor_pool;
|
||||||
|
|
||||||
|
DECLARE_VK_PFN(vkCreateInstance);
|
||||||
|
DECLARE_VK_PFN(vkEnumerateInstanceExtensionProperties);
|
||||||
|
#define VK_INSTANCE_PFN DECLARE_VK_PFN
|
||||||
|
#define VK_DEVICE_PFN DECLARE_VK_PFN
|
||||||
|
#include "vulkan_procs.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VK_CALL(f) (context->f)
|
||||||
|
|
||||||
|
static inline bool vk_extension_properties_contain(const VkExtensionProperties *extensions,
|
||||||
|
uint32_t count, const char *extension_name)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (!strcmp(extensions[i].extensionName, extension_name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vulkan_extension_list
|
||||||
|
{
|
||||||
|
const char **names;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void check_instance_extensions(const struct vulkan_test_context *context,
|
||||||
|
const char **instance_extensions, size_t instance_extension_count,
|
||||||
|
struct vulkan_extension_list *enabled_extensions)
|
||||||
|
{
|
||||||
|
VkExtensionProperties *extensions;
|
||||||
|
uint32_t count, i;
|
||||||
|
|
||||||
|
enabled_extensions->names = calloc(instance_extension_count, sizeof(*enabled_extensions->names));
|
||||||
|
enabled_extensions->count = 0;
|
||||||
|
|
||||||
|
VK_CALL(vkEnumerateInstanceExtensionProperties(NULL, &count, NULL));
|
||||||
|
extensions = calloc(count, sizeof(*extensions));
|
||||||
|
VK_CALL(vkEnumerateInstanceExtensionProperties(NULL, &count, extensions));
|
||||||
|
|
||||||
|
for (i = 0; i < instance_extension_count; ++i)
|
||||||
|
{
|
||||||
|
const char *name = instance_extensions[i];
|
||||||
|
|
||||||
|
if (vk_extension_properties_contain(extensions, count, name))
|
||||||
|
enabled_extensions->names[enabled_extensions->count++] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool vulkan_test_context_init_instance(struct vulkan_test_context *context,
|
||||||
|
const char **instance_extensions, size_t instance_extension_count)
|
||||||
|
{
|
||||||
|
VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
|
||||||
|
struct vulkan_extension_list enabled_extensions;
|
||||||
|
DECLARE_VK_PFN(vkGetInstanceProcAddr)
|
||||||
|
void *libvulkan;
|
||||||
|
uint32_t count;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
memset(context, 0, sizeof(*context));
|
||||||
|
|
||||||
|
if (!(libvulkan = vkd3d_dlopen(SONAME_LIBVULKAN)))
|
||||||
|
{
|
||||||
|
skip("Failed to load %s: %s.\n", SONAME_LIBVULKAN, vkd3d_dlerror());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vkGetInstanceProcAddr = vkd3d_dlsym(libvulkan, "vkGetInstanceProcAddr");
|
||||||
|
|
||||||
|
context->vkCreateInstance = (void *)vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
||||||
|
context->vkEnumerateInstanceExtensionProperties = (void *)vkGetInstanceProcAddr(NULL,
|
||||||
|
"vkEnumerateInstanceExtensionProperties");
|
||||||
|
|
||||||
|
check_instance_extensions(context, instance_extensions, instance_extension_count, &enabled_extensions);
|
||||||
|
instance_desc.ppEnabledExtensionNames = enabled_extensions.names;
|
||||||
|
instance_desc.enabledExtensionCount = enabled_extensions.count;
|
||||||
|
vr = VK_CALL(vkCreateInstance(&instance_desc, NULL, &context->instance));
|
||||||
|
free(enabled_extensions.names);
|
||||||
|
if (vr < 0)
|
||||||
|
{
|
||||||
|
skip("Failed to create a Vulkan instance, vr %d.\n", vr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VK_INSTANCE_PFN(name) context->name = (void *)vkGetInstanceProcAddr(context->instance, #name);
|
||||||
|
#include "vulkan_procs.h"
|
||||||
|
|
||||||
|
count = 1;
|
||||||
|
if ((vr = VK_CALL(vkEnumeratePhysicalDevices(context->instance, &count, &context->phys_device))) < 0)
|
||||||
|
{
|
||||||
|
skip("Failed to enumerate physical devices, vr %d.\n", vr);
|
||||||
|
goto out_destroy_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
skip("No Vulkan devices are available.\n");
|
||||||
|
goto out_destroy_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
out_destroy_instance:
|
||||||
|
VK_CALL(vkDestroyInstance(context->instance, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool get_vulkan_queue_index(const struct vulkan_test_context *context,
|
||||||
|
VkQueueFlags queue_flag, uint32_t *index)
|
||||||
|
{
|
||||||
|
VkQueueFamilyProperties *queue_properties;
|
||||||
|
uint32_t count, i;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(context->phys_device, &count, NULL));
|
||||||
|
queue_properties = malloc(count * sizeof(*queue_properties));
|
||||||
|
VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(context->phys_device, &count, queue_properties));
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (queue_properties[i].queueFlags & queue_flag)
|
||||||
|
{
|
||||||
|
free(queue_properties);
|
||||||
|
*index = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(queue_properties);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool vulkan_test_context_init_device(struct vulkan_test_context *context,
|
||||||
|
const VkDeviceCreateInfo *device_desc, uint32_t queue_index,
|
||||||
|
uint32_t max_resource_count, uint32_t max_sampler_count)
|
||||||
|
{
|
||||||
|
VkDescriptorPoolCreateInfo descriptor_pool_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
|
||||||
|
VkCommandBufferAllocateInfo cmd_buffer_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
|
||||||
|
VkCommandPoolCreateInfo command_pool_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
|
||||||
|
VkDescriptorPoolSize descriptor_pool_sizes[6];
|
||||||
|
VkDevice device;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
if ((vr = VK_CALL(vkCreateDevice(context->phys_device, device_desc, NULL, &device))))
|
||||||
|
{
|
||||||
|
skip("Failed to create device, vr %d.\n", vr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
context->device = device;
|
||||||
|
|
||||||
|
#define VK_DEVICE_PFN(name) context->name = (void *)VK_CALL(vkGetDeviceProcAddr(device, #name));
|
||||||
|
#include "vulkan_procs.h"
|
||||||
|
|
||||||
|
VK_CALL(vkGetDeviceQueue(device, queue_index, 0, &context->queue));
|
||||||
|
|
||||||
|
command_pool_desc.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
|
command_pool_desc.queueFamilyIndex = queue_index;
|
||||||
|
|
||||||
|
VK_CALL(vkCreateCommandPool(device, &command_pool_desc, NULL, &context->command_pool));
|
||||||
|
|
||||||
|
cmd_buffer_desc.commandPool = context->command_pool;
|
||||||
|
cmd_buffer_desc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
cmd_buffer_desc.commandBufferCount = 1;
|
||||||
|
|
||||||
|
VK_CALL(vkAllocateCommandBuffers(device, &cmd_buffer_desc, &context->cmd_buffer));
|
||||||
|
|
||||||
|
assert(max_resource_count);
|
||||||
|
|
||||||
|
descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
descriptor_pool_sizes[0].descriptorCount = max_resource_count;
|
||||||
|
descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||||
|
descriptor_pool_sizes[1].descriptorCount = max_resource_count;
|
||||||
|
descriptor_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
descriptor_pool_sizes[2].descriptorCount = max_resource_count;
|
||||||
|
descriptor_pool_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
|
||||||
|
descriptor_pool_sizes[3].descriptorCount = max_resource_count;
|
||||||
|
descriptor_pool_sizes[4].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||||
|
descriptor_pool_sizes[4].descriptorCount = max_resource_count;
|
||||||
|
descriptor_pool_sizes[5].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||||
|
descriptor_pool_sizes[5].descriptorCount = max_sampler_count;
|
||||||
|
|
||||||
|
descriptor_pool_desc.maxSets = 1;
|
||||||
|
descriptor_pool_desc.poolSizeCount = ARRAY_SIZE(descriptor_pool_sizes) - !max_sampler_count;
|
||||||
|
descriptor_pool_desc.pPoolSizes = descriptor_pool_sizes;
|
||||||
|
|
||||||
|
VK_CALL(vkCreateDescriptorPool(device, &descriptor_pool_desc, NULL, &context->descriptor_pool));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vulkan_test_context_destroy(const struct vulkan_test_context *context)
|
||||||
|
{
|
||||||
|
VkDevice device = context->device;
|
||||||
|
|
||||||
|
VK_CALL(vkDestroyDescriptorPool(device, context->descriptor_pool, NULL));
|
||||||
|
VK_CALL(vkFreeCommandBuffers(device, context->command_pool, 1, &context->cmd_buffer));
|
||||||
|
VK_CALL(vkDestroyCommandPool(device, context->command_pool, NULL));
|
||||||
|
VK_CALL(vkDestroyDevice(device, NULL));
|
||||||
|
VK_CALL(vkDestroyInstance(context->instance, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __VKD3D_VULKAN_UTILS_H */
|
Loading…
Reference in New Issue
Block a user