summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp118
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h1
-rw-r--r--drivers/vulkan/vulkan_context.cpp221
-rw-r--r--drivers/vulkan/vulkan_context.h5
-rw-r--r--drivers/vulkan/vulkan_hooks.h48
5 files changed, 298 insertions, 95 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index ddeac220ec..cda8871f3e 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -2118,6 +2118,124 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
return id;
}
+RID RenderingDeviceVulkan::texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers) {
+ _THREAD_SAFE_METHOD_
+ // This method creates a texture object using a VkImage created by an extension, module or other external source (OpenXR uses this).
+ VkImage image = (VkImage)p_image;
+
+ Texture texture;
+ texture.image = image;
+ // if we leave texture.allocation as a nullptr, would that be enough to detect we don't "own" the image?
+ // also leave texture.allocation_info alone
+ // we'll set texture.view later on
+ texture.type = p_type;
+ texture.format = p_format;
+ texture.samples = p_samples;
+ texture.width = p_width;
+ texture.height = p_height;
+ texture.depth = p_depth;
+ texture.layers = p_layers;
+ texture.mipmaps = 0; // maybe make this settable too?
+ texture.usage_flags = p_flags;
+ texture.base_mipmap = 0;
+ texture.base_layer = 0;
+ texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
+ texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
+
+ // Do we need to do something with texture.layout ?
+
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ texture.read_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ texture.barrier_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+
+ // if (format_has_stencil(p_format.format)) {
+ // texture.barrier_aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+ // }
+ } else {
+ texture.read_aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+ texture.barrier_aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+
+ // Create a view for us to use
+
+ VkImageViewCreateInfo image_view_create_info;
+ image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ image_view_create_info.pNext = nullptr;
+ image_view_create_info.flags = 0;
+ image_view_create_info.image = texture.image;
+
+ static const VkImageViewType view_types[TEXTURE_TYPE_MAX] = {
+ VK_IMAGE_VIEW_TYPE_1D,
+ VK_IMAGE_VIEW_TYPE_2D,
+ VK_IMAGE_VIEW_TYPE_3D,
+ VK_IMAGE_VIEW_TYPE_CUBE,
+ VK_IMAGE_VIEW_TYPE_1D_ARRAY,
+ VK_IMAGE_VIEW_TYPE_2D_ARRAY,
+ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
+ };
+
+ image_view_create_info.viewType = view_types[texture.type];
+ image_view_create_info.format = vulkan_formats[texture.format];
+
+ static const VkComponentSwizzle component_swizzles[TEXTURE_SWIZZLE_MAX] = {
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_ZERO,
+ VK_COMPONENT_SWIZZLE_ONE,
+ VK_COMPONENT_SWIZZLE_R,
+ VK_COMPONENT_SWIZZLE_G,
+ VK_COMPONENT_SWIZZLE_B,
+ VK_COMPONENT_SWIZZLE_A
+ };
+
+ // hardcode for now, maybe make this settable from outside..
+ image_view_create_info.components.r = component_swizzles[TEXTURE_SWIZZLE_R];
+ image_view_create_info.components.g = component_swizzles[TEXTURE_SWIZZLE_G];
+ image_view_create_info.components.b = component_swizzles[TEXTURE_SWIZZLE_B];
+ image_view_create_info.components.a = component_swizzles[TEXTURE_SWIZZLE_A];
+
+ image_view_create_info.subresourceRange.baseMipLevel = 0;
+ image_view_create_info.subresourceRange.levelCount = texture.mipmaps;
+ image_view_create_info.subresourceRange.baseArrayLayer = 0;
+ image_view_create_info.subresourceRange.layerCount = texture.layers;
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ } else {
+ image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+
+ VkResult err = vkCreateImageView(device, &image_view_create_info, nullptr, &texture.view);
+
+ if (err) {
+ // vmaDestroyImage(allocator, texture.image, texture.allocation);
+ ERR_FAIL_V_MSG(RID(), "vkCreateImageView failed with error " + itos(err) + ".");
+ }
+
+ //barrier to set layout
+ {
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = 0;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ image_memory_barrier.newLayout = texture.layout;
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = texture.image;
+ image_memory_barrier.subresourceRange.aspectMask = texture.barrier_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = 0;
+ image_memory_barrier.subresourceRange.levelCount = texture.mipmaps;
+ image_memory_barrier.subresourceRange.baseArrayLayer = 0;
+ image_memory_barrier.subresourceRange.layerCount = texture.layers;
+
+ vkCmdPipelineBarrier(frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+
+ RID id = texture_owner.make_rid(texture);
+
+ return id;
+}
+
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps, TextureSliceType p_slice_type) {
_THREAD_SAFE_METHOD_
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6510893196..3e4327667b 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -1037,6 +1037,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>());
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
+ virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index e4aab8d868..3551b5d6c4 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -46,6 +46,8 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define APP_SHORT_NAME "GodotEngine"
+VulkanHooks *VulkanContext::vulkan_hooks = nullptr;
+
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
@@ -695,19 +697,27 @@ Error VulkanContext::_create_instance() {
inst_info.pNext = &dbg_report_callback_create_info;
}
- VkResult err = vkCreateInstance(&inst_info, nullptr, &inst);
- ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
- "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
- "vkCreateInstance Failure");
- ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
- "Cannot find a specified extension library.\n"
- "Make sure your layers path is set appropriately.\n"
- "vkCreateInstance Failure");
- ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
- "vkCreateInstance failed.\n\n"
- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
- "Please look at the Getting Started guide for additional information.\n"
- "vkCreateInstance Failure");
+ VkResult err;
+
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->create_vulkan_instance(&inst_info, &inst)) {
+ return ERR_CANT_CREATE;
+ }
+ } else {
+ err = vkCreateInstance(&inst_info, nullptr, &inst);
+ ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
+ "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
+ "Cannot find a specified extension library.\n"
+ "Make sure your layers path is set appropriately.\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
+ "vkCreateInstance failed.\n\n"
+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
+ "Please look at the Getting Started guide for additional information.\n"
+ "vkCreateInstance Failure");
+ }
inst_initialized = true;
@@ -820,107 +830,122 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
{ 0, nullptr },
};
- // TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
- // The device should really be a preference, but for now choosing a discrete GPU over the
- // integrated one is better than the default.
-
int32_t device_index = -1;
- int type_selected = -1;
- print_verbose("Vulkan devices:");
- for (uint32_t i = 0; i < gpu_count; ++i) {
- VkPhysicalDeviceProperties props;
- vkGetPhysicalDeviceProperties(physical_devices[i], &props);
-
- bool present_supported = false;
-
- uint32_t device_queue_family_count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
- VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
- vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
- for (uint32_t j = 0; j < device_queue_family_count; j++) {
- VkBool32 supports;
- vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
- if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
- present_supported = true;
- } else {
- continue;
- }
- }
- String name = props.deviceName;
- String vendor = "Unknown";
- String dev_type;
- switch (props.deviceType) {
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
- dev_type = "Discrete";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
- dev_type = "Integrated";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
- dev_type = "Virtual";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
- dev_type = "CPU";
- } break;
- default: {
- dev_type = "Other";
- } break;
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->get_physical_device(&gpu)) {
+ return ERR_CANT_CREATE;
}
- uint32_t vendor_idx = 0;
- while (vendor_names[vendor_idx].name != nullptr) {
- if (props.vendorID == vendor_names[vendor_idx].id) {
- vendor = vendor_names[vendor_idx].name;
+
+ // not really needed but nice to print the correct entry
+ for (uint32_t i = 0; i < gpu_count; ++i) {
+ if (physical_devices[i] == gpu) {
+ device_index = i;
break;
}
- vendor_idx++;
}
- free(device_queue_props);
- print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
-
- if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
+ } else {
+ // TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
+ // The device should really be a preference, but for now choosing a discrete GPU over the
+ // integrated one is better than the default.
+
+ int type_selected = -1;
+ print_verbose("Vulkan devices:");
+ for (uint32_t i = 0; i < gpu_count; ++i) {
+ VkPhysicalDeviceProperties props;
+ vkGetPhysicalDeviceProperties(physical_devices[i], &props);
+
+ bool present_supported = false;
+
+ uint32_t device_queue_family_count = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
+ VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
+ vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
+ for (uint32_t j = 0; j < device_queue_family_count; j++) {
+ VkBool32 supports;
+ vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
+ if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
+ present_supported = true;
+ } else {
+ continue;
+ }
+ }
+ String name = props.deviceName;
+ String vendor = "Unknown";
+ String dev_type;
switch (props.deviceType) {
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
- if (type_selected < 4) {
- type_selected = 4;
- device_index = i;
- }
+ dev_type = "Discrete";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
- if (type_selected < 3) {
- type_selected = 3;
- device_index = i;
- }
+ dev_type = "Integrated";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
- if (type_selected < 2) {
- type_selected = 2;
- device_index = i;
- }
+ dev_type = "Virtual";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
- if (type_selected < 1) {
- type_selected = 1;
- device_index = i;
- }
+ dev_type = "CPU";
} break;
default: {
- if (type_selected < 0) {
- type_selected = 0;
- device_index = i;
- }
+ dev_type = "Other";
} break;
}
+ uint32_t vendor_idx = 0;
+ while (vendor_names[vendor_idx].name != nullptr) {
+ if (props.vendorID == vendor_names[vendor_idx].id) {
+ vendor = vendor_names[vendor_idx].name;
+ break;
+ }
+ vendor_idx++;
+ }
+ free(device_queue_props);
+ print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
+
+ if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other.
+ switch (props.deviceType) {
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
+ if (type_selected < 4) {
+ type_selected = 4;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
+ if (type_selected < 3) {
+ type_selected = 3;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
+ if (type_selected < 2) {
+ type_selected = 2;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
+ if (type_selected < 1) {
+ type_selected = 1;
+ device_index = i;
+ }
+ } break;
+ default: {
+ if (type_selected < 0) {
+ type_selected = 0;
+ device_index = i;
+ }
+ } break;
+ }
+ }
}
- }
- int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
- if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
- device_index = user_device_index;
- }
+ int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
+ if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
+ device_index = user_device_index;
+ }
- ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
+ ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
+
+ gpu = physical_devices[device_index];
+ }
- gpu = physical_devices[device_index];
free(physical_devices);
/* Look for device extensions */
@@ -1148,8 +1173,14 @@ Error VulkanContext::_create_device() {
sdevice.queueCreateInfoCount = 2;
}
- err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->create_vulkan_device(&sdevice, &device)) {
+ return ERR_CANT_CREATE;
+ }
+ } else {
+ err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
+ ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ }
return OK;
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index d4052666e3..8c0111714c 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -45,6 +45,8 @@
#include <vulkan/vulkan.h>
#endif
+#include "vulkan_hooks.h"
+
class VulkanContext {
public:
struct SubgroupCapabilities {
@@ -86,6 +88,7 @@ private:
FRAME_LAG = 2
};
+ static VulkanHooks *vulkan_hooks;
VkInstance inst = VK_NULL_HANDLE;
VkPhysicalDevice gpu = VK_NULL_HANDLE;
VkPhysicalDeviceProperties gpu_props;
@@ -267,6 +270,8 @@ public:
VkQueue get_graphics_queue() const;
uint32_t get_graphics_queue_family_index() const;
+ static void set_vulkan_hooks(VulkanHooks *p_vulkan_hooks) { vulkan_hooks = p_vulkan_hooks; };
+
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);
int window_get_height(DisplayServer::WindowID p_window = 0);
diff --git a/drivers/vulkan/vulkan_hooks.h b/drivers/vulkan/vulkan_hooks.h
new file mode 100644
index 0000000000..3f244b4d45
--- /dev/null
+++ b/drivers/vulkan/vulkan_hooks.h
@@ -0,0 +1,48 @@
+/*************************************************************************/
+/* vulkan_hooks.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VULKAN_HOOKS_H
+#define VULKAN_HOOKS_H
+
+#ifdef USE_VOLK
+#include <volk.h>
+#else
+#include <vulkan/vulkan.h>
+#endif
+
+class VulkanHooks {
+public:
+ virtual bool create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) { return false; };
+ virtual bool get_physical_device(VkPhysicalDevice *r_device) { return false; };
+ virtual bool create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) { return false; };
+ virtual ~VulkanHooks(){};
+};
+
+#endif