Files
window_renderer_test/src/gpu/vulkan/vk_gpu.c
T

2875 lines
166 KiB
C

// vim:fileencoding=utf-8:foldmethod=marker
#include "vulkan_profiles/vulkan_profiles.h"
#include "../gpu.h"
#include "../../config/config_inc.h"
#include "../../utils/utils_inc.h"
#include "../../window/window_inc.h"
#include "../../wapp/wapp.h"
#include "../../cglm/struct.h"
#include <stdint.h>
#ifdef USE_SDL_WINDOW_BACKEND
#include <SDL3/SDL_vulkan.h>
#else
#error "No window backend selected"
#endif
#include <volk/volk.h>
#include <vulkan/vulkan_core.h>
#include <vma/vk_mem_alloc.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define clamp(value, minimum, maximum) (max((minimum), (min((value), (maximum)))))
wp_intern WpLogger logger = wpLogMakeLogger(wpStr8LitRo("Vulkan Wrapper"));
typedef VkPhysicalDevice *VkPhysicalDeviceArray;
typedef VkQueueFamilyProperties2 *VkQueueFamilyProperties2Array;
typedef VkImage *VkImageArray;
typedef VkImageView *VkImageViewArray;
typedef VkFormat *VkFormatArray;
typedef VkSurfaceFormat2KHR *VkSurfaceFormat2KHRArray;
typedef VkCommandBuffer *VkCommandBufferArray;
typedef VkDescriptorPoolSize *VkDescriptorPoolSizeArray;
typedef VkDescriptorBindingFlags *VkDescriptorBindingFlagsArray;
typedef VkDescriptorSetLayoutBindingFlagsCreateInfo *VkDescriptorSetLayoutBindingFlagsCreateInfoArray;
typedef VkDescriptorSetLayoutBinding *VkDescriptorSetLayoutBindingArray;
typedef VkDescriptorSetLayout *VkDescriptorSetLayoutArray;
typedef VkDescriptorSetVariableDescriptorCountAllocateInfo *VkDescriptorSetVariableDescriptorCountAllocateInfoArray;
typedef VkDescriptorSet *VkDescriptorSetArray;
typedef VkWriteDescriptorSet *VkWriteDescriptorSetArray;
typedef VkDescriptorBufferInfo *VkDescriptorBufferInfoArray;
typedef VkDescriptorImageInfo *VkDescriptorImageInfoArray;
typedef VkPushConstantRange *VkPushConstantRangeArray;
typedef VkGraphicsPipelineCreateInfo *VkGraphicsPipelineCreateInfoArray;
typedef VkComputePipelineCreateInfo *VkComputePipelineCreateInfoArray;
typedef VkPipeline *VkPipelineArray;
typedef VkVertexInputBindingDescription *VkVertexInputBindingDescriptionArray;
typedef VkVertexInputAttributeDescription *VkVertexInputAttributeDescriptionArray;
typedef VkViewport *VkViewportArray;
typedef VkRect2D *VkRect2DArray;
typedef VkPipelineColorBlendAttachmentState *VkPipelineColorBlendAttachmentStateArray;
typedef VkPipelineShaderStageCreateInfo *VkPipelineShaderStageCreateInfoArray;
typedef VkPipelineVertexInputStateCreateInfo *VkPipelineVertexInputStateCreateInfoArray;
typedef VkPipelineInputAssemblyStateCreateInfo *VkPipelineInputAssemblyStateCreateInfoArray;
typedef VkPipelineTessellationStateCreateInfo *VkPipelineTessellationStateCreateInfoArray;
typedef VkPipelineViewportStateCreateInfo *VkPipelineViewportStateCreateInfoArray;
typedef VkPipelineRasterizationStateCreateInfo *VkPipelineRasterizationStateCreateInfoArray;
typedef VkPipelineMultisampleStateCreateInfo *VkPipelineMultisampleStateCreateInfoArray;
typedef VkPipelineDepthStencilStateCreateInfo *VkPipelineDepthStencilStateCreateInfoArray;
typedef VkPipelineColorBlendStateCreateInfo *VkPipelineColorBlendStateCreateInfoArray;
typedef VkPipelineRenderingCreateInfo *VkPipelineRenderingCreateInfoArray;
typedef VkDynamicState *VkDynamicStateArray;
struct GpuInstance {
VkInstance vk_instance;
VpProfileProperties profile;
};
struct GpuPhysicalDeviceInternal {
VkPhysicalDevice vk_physical_device;
u32 queue_family_index;
};
struct GpuSurface {
VkSurfaceCapabilitiesKHR capabilities;
const GpuInstance *instance;
VkSurfaceKHR vk_surface;
const Window *window;
};
struct GpuDevice {
GpuPhysicalDevice physical_device;
VkDevice vk_device;
VkQueue vk_queue;
VmaAllocator allocator;
};
struct GpuSampler {
GpuDevice *device;
VkSampler vk_sampler;
};
struct GpuImage {
GpuDevice *device;
VmaAllocation allocation;
VkImage vk_image;
VkImageView vk_view;
ivec3s size;
VkFormat format;
};
struct GpuSwapchain {
GpuDevice *device;
VkSwapchainKHR vk_swapchain;
VkExtent2D extent;
GpuImageArray images;
GpuImage depth;
};
struct GpuBufferInternal {
VmaAllocationInfo allocation_info;
VkBuffer vk_buffer;
VmaAllocation allocation;
};
struct GpuFence {
GpuDevice *device;
VkFence vk_fence;
};
struct GpuSemaphore {
GpuDevice *device;
VkSemaphore vk_semaphore;
};
struct GpuCommandPool {
GpuDevice *device;
VkCommandPool vk_pool;
};
struct GpuCommandBuffer {
GpuCommandPool *pool;
VkCommandBuffer vk_buffer;
};
struct GpuDescriptorPool {
GpuDevice *device;
VkDescriptorPool vk_pool;
};
struct GpuDescriptorSetLayout {
GpuDevice *device;
VkDescriptorSetLayout vk_layout;
u32 variable_descriptor_count;
};
struct GpuDescriptorSet {
GpuDescriptorPool *pool;
GpuDescriptorSetLayout *layout;
VkDescriptorSet vk_set;
};
struct GpuShader {
GpuDevice *device;
VkShaderModule vk_shader;
};
struct GpuPipelineLayout {
GpuDevice *device;
VkPipelineLayout vk_layout;
};
struct GpuPipeline {
GpuPipelineLayout *layout;
VkPipeline vk_pipeline;
};
typedef struct VkExtensions {
const char *const *extensions;
u32 count;
} VkExtensions;
typedef struct GraphicsPipelinesTotalCounts {
u64 total_vertex_input_bindings_count;
u64 total_vertex_input_attributes_count;
u64 total_viewports_count;
u64 total_scissors_count;
u64 total_color_blend_attachments_count;
u64 total_shader_stages_count;
} GraphicsPipelinesTotalCounts;
typedef struct GraphicsPipelinesTempArrays {
VkPipelineVertexInputStateCreateInfoArray vertex_input_states;
VkPipelineInputAssemblyStateCreateInfoArray input_assembly_states;
VkPipelineTessellationStateCreateInfoArray tesselation_states;
VkPipelineViewportStateCreateInfoArray viewport_states;
VkPipelineRasterizationStateCreateInfoArray rasterization_states;
VkPipelineMultisampleStateCreateInfoArray multisample_states;
VkPipelineDepthStencilStateCreateInfoArray depth_stencil_states;
VkPipelineColorBlendStateCreateInfoArray color_blend_states;
VkPipelineRenderingCreateInfoArray dynamic_rendering_infos;
VkFormatArray color_attachment_formats;
VkVertexInputBindingDescriptionArray vertex_bindings;
u64 vertex_bindings_offset;
VkVertexInputAttributeDescriptionArray vertex_attributes;
u64 vertex_attributes_offset;
VkPipelineColorBlendAttachmentStateArray color_blend_attachments;
u64 color_blend_attachments_offset;
VkPipelineShaderStageCreateInfoArray shader_stages;
u64 shader_stages_offset;
} GraphicsPipelinesTempArrays;
typedef enum GpuDescriptorCategory {
GPU_DESCRIPTOR_CATEGORY_IMAGE,
GPU_DESCRIPTOR_CATEGORY_BUFFER,
GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER,
GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK,
} GpuDescriptorCategory;
wp_intern VkExtensions getInstanceExtensions(void);
wp_intern GpuPhysicalDeviceType vkDeviceTypeToGpuDeviceType(VkPhysicalDeviceType type);
wp_intern VkPhysicalDeviceType gpuDeviceTypeToVkDeviceType(GpuPhysicalDeviceType type);
wp_intern i32 findQueueFamily(const WpAllocator *allocator, VkInstance instance,
VkPhysicalDevice physical_device, GpuPhysicalDeviceOps ops);
wp_intern VkQueueFlags queueFlagsFromOps(GpuPhysicalDeviceOps ops);
wp_intern b8 presentationSupported(VkInstance instance, VkPhysicalDevice device,
u32 queue_family_index);
wp_intern b8 windowBackendCreateSurface(const Window *window, VkInstance instance,
VkSurfaceKHR *surface);
wp_intern VkFormat vkFormatFromGpuFormat(GpuFormat format);
wp_intern GpuFormat gpuFormatFromVkFormat(VkFormat format);
wp_intern VkColorSpaceKHR vkColorspaceFromGpuColorspace(GpuColorspace colorspace);
wp_intern GpuColorspace gpuColorspaceFromVkColorspace(VkColorSpaceKHR colorspace);
wp_intern VkPresentModeKHR vkPresentModeFromGpuPresentMode(GpuPresentMode mode);
wp_intern GpuPresentMode gpuPresentModeFromVkPresentMode(VkPresentModeKHR mode);
wp_intern VkImageType vkImageTypeFromGpuImageType(GpuImageType type);
wp_intern GpuImageType gpuImageTypeFromVkImageType(VkImageType type);
wp_intern VkImageViewType vkImageViewTypeFromGpuImageType(GpuImageType type);
wp_intern GpuImageType gpuImageTypeFromVkImageViewType(VkImageViewType type);
wp_intern VkSampleCountFlagBits vkSampleCountFromGpuSampleCount(GpuSampleCount samples);
wp_intern GpuSampleCount gpuSampleCountFromVkSampleCount(VkSampleCountFlagBits samples);
wp_intern VkImageTiling vkImageTilingFromGpuImageTiling(GpuImageTiling tiling);
wp_intern GpuImageTiling gpuImageTilingFromVkImageTiling(VkImageTiling tiling);
wp_intern VkImageUsageFlags vkImageUsageFromGpuImageUsage(GpuImageUsage usage);
wp_intern GpuImageUsage gpuImageUsageFromVkImageUsage(VkImageUsageFlags usage);
wp_intern VkImageLayout vkImageLayoutFromGpuImageLayout(GpuImageLayout layout);
wp_intern GpuImageLayout gpuImageLayoutFromVkImageLayout(VkImageLayout layout);
wp_intern VkImageAspectFlags vkImageAspectFromGpuImageAspect(GpuImageAspect aspect);
wp_intern GpuImageAspect gpuImageAspectFromVkImageAspect(VkImageAspectFlags aspect);
wp_intern VkBufferUsageFlags2 vkBufferUsageFromGpuBufferUsage(GpuBufferUsage usage);
wp_intern GpuBufferUsage gpuBufferUsageFromVkBufferUsage(VkBufferUsageFlags2 usage);
wp_intern VkPipelineStageFlags2 vkPipelineStagesFromGpuPipelineStages(GpuPipelineStageFlags stage);
wp_intern GpuPipelineStageFlags gpuPipelineStagesFromVkPipelineStages(VkPipelineStageFlags2 stage);
wp_intern VkAccessFlags2 vkAccessFlagsFromGpuAccessFlags(GpuAccessFlags access);
wp_intern GpuAccessFlags gpuAccessFlagsFromVkAccessFlags(VkAccessFlags2 access);
wp_intern VkFilter vkFilterFromGpuFilter(GpuFilter filter);
wp_intern GpuFilter gpuFilterFromVkFilter(VkFilter filter);
wp_intern VkSamplerMipmapMode vkSamplerMipmapModeFromGpuSamplerMipmapMode(GpuSamplerMipmapMode mode);
wp_intern GpuSamplerMipmapMode gpuSamplerMipmapModeFromVkSamplerMipmapMode(VkSamplerMipmapMode mode);
wp_intern VkSamplerAddressMode vkSamplerAddressModeFromGpuSamplerAddressMode(GpuSamplerAddressMode mode);
wp_intern GpuSamplerAddressMode gpuSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode mode);
wp_intern VkCompareOp vkCompareOpFromGpuCompareOp(GpuCompareOp op);
wp_intern GpuCompareOp gpuCompareOpFromVkCompareOp(VkCompareOp op);
wp_intern VkDescriptorType vkDescriptorTypeFromGpuDescriptorType(GpuDescriptorType type);
wp_intern GpuDescriptorType gpuDescriptorTypeFromVkDescriptorType(VkDescriptorType type);
wp_intern VkShaderStageFlags vkShaderStageFromGpuShaderStage(GpuShaderStage stages);
wp_intern GpuShaderStage gpuShaderStageFromVkShaderStage(VkShaderStageFlags stages);
wp_intern GpuDescriptorCategory descriptorCategoryFromDescriptorType(GpuDescriptorType type);
wp_intern u64 retrieveDescriptorImageInfos(const GpuDescriptorSetWriteInfo *info,
VkWriteDescriptorSet *desc_set_write,
VkDescriptorImageInfoArray desc_img_infos,
u64 img_info_offset);
wp_intern u64 retrieveDescriptorBufferInfos(const GpuDescriptorSetWriteInfo *info,
VkWriteDescriptorSet *desc_set_write,
VkDescriptorBufferInfoArray desc_buf_infos,
u64 buf_info_offset);
wp_intern GraphicsPipelinesTotalCounts queryGraphicsPipelinesRequestTotalCounts(GpuGraphicsPipelinesCreateRequest request);
wp_intern GraphicsPipelinesTempArrays allocateGraphicsPipelinesTempArrays(const WpAllocator *allocator,
GpuGraphicsPipelinesCreateRequest request);
wp_intern VkVertexInputRate vkVertexInputRateFromGpuVertexInputRate(GpuVertexInputRate rate);
wp_intern GpuVertexInputRate gpuVertexInputRateFromVkVertexInputRate(VkVertexInputRate rate);
wp_intern VkPrimitiveTopology vkPrimitiveTopologyFromGpuPrimitiveTopology(GpuPrimitiveTopology topology);
wp_intern GpuPrimitiveTopology gpuPrimitiveTopologyFromVkPrimitiveTopology(VkPrimitiveTopology topology);
wp_intern VkPolygonMode vkPolygonModeFromGpuPolygonMode(GpuPolygonMode mode);
wp_intern GpuPolygonMode gpuPolygonModeFromVkPolygonMode(VkPolygonMode mode);
wp_intern VkCullModeFlags vkCullModeFromGpuCullMode(GpuCullMode mode);
wp_intern GpuCullMode gpuCullModeFromVkCullMode(VkCullModeFlags mode);
wp_intern VkFrontFace vkFrontFaceFromGpuFrontFace(GpuFrontFace front_face);
wp_intern GpuFrontFace gpuFrontFaceFromVkFrontFace(VkFrontFace front_face);
wp_intern VkStencilOp vkStencilOpFromGpuStencil(GpuStencilOp op);
wp_intern GpuStencilOp gpuStencilOpFromVkStencil(VkStencilOp op);
wp_intern VkBlendFactor vkBlendFactorFromGpuBlendFactor(GpuBlendFactor factor);
wp_intern GpuBlendFactor gpuBlendFactorFromVkBlendFactor(VkBlendFactor factor);
wp_intern VkBlendOp vkBlendOpFromGpuBlendOp(GpuBlendOp op);
wp_intern GpuBlendOp gpuBlendOpFromVkBlendOp(VkBlendOp op);
wp_intern VkColorComponentFlags vkColorComponentFlagsFromGpuColorComponentFlags(GpuColorComponentFlags flags);
wp_intern GpuColorComponentFlags gpuColorComponentFlagsFromVkColorComponentFlags(VkColorComponentFlags flags);
wp_intern VkLogicOp vkLogicOpFromGpuLogicOp(GpuLogicOp op);
wp_intern GpuLogicOp gpuLogicOpFromVkLogicOp(VkLogicOp op);
GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request) {
assertWithLogger(volkInitialize() == VK_SUCCESS, &logger, "Failed to initialise volk");
VpProfileProperties profile = {
.profileName = VP_TEST_WINDOW_RENDERER_NAME,
.specVersion = VP_TEST_WINDOW_RENDERER_SPEC_VERSION,
};
VkExtensions instance_extensions = getInstanceExtensions();
VkBool32 supported = VK_FALSE;
vpGetInstanceProfileSupport(NULL, &profile, &supported);
assertWithLogger(supported, &logger, "Profile not supported");
GpuInstance *instance = wpMemAllocatorAlloc(allocator, sizeof(GpuInstance));
assertWithLogger(instance != NULL, &logger, "Failed to allocate instance");
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.apiVersion = VP_TEST_WINDOW_RENDERER_MIN_API_VERSION,
.pApplicationName = request.app_name,
.applicationVersion = request.app_version,
};
VkInstanceCreateInfo instance_info = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &app_info,
.enabledExtensionCount = instance_extensions.count,
.ppEnabledExtensionNames = instance_extensions.extensions,
};
VpInstanceCreateInfo vp_instance_info = {
.pCreateInfo = &instance_info,
.enabledFullProfileCount = 1,
.pEnabledFullProfiles = &profile,
};
assertWithLogger(vpCreateInstance(&vp_instance_info, NULL, &instance->vk_instance) == VK_SUCCESS, &logger,
"Failed to create Vulkan instance");
instance->profile = profile;
volkLoadInstance(instance->vk_instance);
wpLogInfo(&logger, wpStr8Lit("Initialised Vulkan GPU successfully"));
return instance;
}
GpuPhysicalDevice gpuFindPhysicalDevice(const WpAllocator *allocator, const WpAllocator *temp,
GpuPhysicalDeviceFindRequest request) {
VkResult vk_result = VK_SUCCESS;
u32 count = 0;
vk_result = vkEnumeratePhysicalDevices(request.instance->vk_instance, &count, NULL);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get physical device count");
VkPhysicalDeviceArray physical_devices = wpArrayAllocCapacity(VkPhysicalDevice, temp, count,
WP_ARRAY_INIT_FILLED);
assertWithLogger(physical_devices != NULL, &logger, "Failed to allocate physical devices");
vk_result = vkEnumeratePhysicalDevices(request.instance->vk_instance, &count, physical_devices);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to enumerate physical devices");
VkBool32 supported = VK_FALSE;
WpStr8 msg = wpStr8Buf(4096);
VkPhysicalDevice device = VK_NULL_HANDLE;
i32 queue_family_index = -1;
for (u32 i = 0; i < count; ++i) {
VkPhysicalDeviceProperties2 properties = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };
vkGetPhysicalDeviceProperties2(physical_devices[i], &properties);
if (properties.properties.apiVersion < VP_TEST_WINDOW_RENDERER_MIN_API_VERSION) {
continue;
}
VkResult profile_support = vpGetPhysicalDeviceProfileSupport(request.instance->vk_instance, physical_devices[i],
&request.instance->profile, &supported);
b8 device_type_match = gpuDeviceTypeToVkDeviceType(request.type) == properties.properties.deviceType;
if (profile_support != VK_SUCCESS || !supported || !device_type_match) {
continue;
}
queue_family_index = findQueueFamily(temp, request.instance->vk_instance, physical_devices[i],
request.ops);
if (queue_family_index == -1) {
continue;
}
device = physical_devices[i];
wpStr8Format(&msg, "Found suitable physical device (Name: %s)", properties.properties.deviceName);
wpLogDebug(&logger, msg);
break;
}
GpuPhysicalDevice physical_device = {0};
assertWithLogger(device != NULL && queue_family_index > -1, &logger, "Failed to find a suitable physical device");
physical_device.internal = wpMemAllocatorAlloc(allocator, sizeof(GpuPhysicalDeviceInternal));
assertWithLogger(physical_device.internal != NULL, &logger, "Failed to allocate physical device internal");
physical_device.instance = request.instance;
physical_device.internal->vk_physical_device = device;
physical_device.internal->queue_family_index = (u32)queue_family_index;
physical_device.type = request.type;
return physical_device;
}
GpuSurface *gpuCreateSurface(const WpAllocator *allocator, GpuSurfaceCreateRequest request) {
VkResult vk_result = VK_SUCCESS;
GpuSurface *surface = wpMemAllocatorAlloc(allocator, sizeof(GpuSurface));
assertWithLogger(surface != NULL, &logger, "Failed to allocate surface");
b8 surface_created = windowBackendCreateSurface(request.window, request.physical_device.instance->vk_instance,
&surface->vk_surface);
assertWithLogger(surface_created, &logger, "Failed to create Vulkan surface");
vk_result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(request.physical_device.internal->vk_physical_device,
surface->vk_surface, &surface->capabilities);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get surface capabilities");
surface->instance = request.physical_device.instance;
surface->window = request.window;
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Created Vulkan surface %p", surface->vk_surface);
wpLogDebug(&logger, msg);
return surface;
}
void gpuDestroySurface(GpuSurface *surface) {
vkDestroySurfaceKHR(surface->instance->vk_instance, surface->vk_surface, NULL);
}
GpuDevice *gpuCreateDevice(const WpAllocator *allocator, GpuPhysicalDevice physical_device) {
VkResult vk_result = VK_SUCCESS;
GpuDevice *device = wpMemAllocatorAlloc(allocator, sizeof(GpuDevice));
assertWithLogger(device != NULL, &logger, "Failed to allocate device internal");
device->physical_device = physical_device;
f32 queue_priority = 1.0f;
VkDeviceQueueCreateInfo device_queue_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueCount = 1,
.queueFamilyIndex = physical_device.internal->queue_family_index,
.pQueuePriorities = &queue_priority,
};
VkDeviceCreateInfo device_create_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &device_queue_create_info,
};
VpDeviceCreateInfo vp_device_create_info = {
.pCreateInfo = &device_create_info,
.enabledFullProfileCount = 1,
.pEnabledFullProfiles = &physical_device.instance->profile,
};
vk_result = vpCreateDevice(physical_device.internal->vk_physical_device, &vp_device_create_info,
NULL, &device->vk_device);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan device");
vkGetDeviceQueue(device->vk_device, device->physical_device.internal->queue_family_index,
0, &device->vk_queue);
VmaVulkanFunctions vk_functions = {
.vkGetInstanceProcAddr = vkGetInstanceProcAddr,
.vkGetDeviceProcAddr = vkGetDeviceProcAddr,
.vkCreateImage = vkCreateImage,
};
VmaAllocatorCreateInfo allocator_create_info = {
.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT |
VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT |
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT,
.instance = physical_device.instance->vk_instance,
.physicalDevice = physical_device.internal->vk_physical_device,
.device = device->vk_device,
.pVulkanFunctions = &vk_functions,
};
vk_result = vmaCreateAllocator(&allocator_create_info, &device->allocator);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan memory allocator");
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Created Vulkan device %p", device->vk_device);
wpLogDebug(&logger, msg);
return device;
}
void gpuDestroyDevice(GpuDevice *device) {
vmaDestroyAllocator(device->allocator);
vkDestroyDevice(device->vk_device, NULL);
}
GpuSwapchain *gpuCreateSwapchain(const WpAllocator *allocator, const WpAllocator *temp,
GpuSwapchainCreateRequest request) {
VkResult vk_result = VK_SUCCESS;
u32 surface_formats_count = 0;
VkPhysicalDeviceSurfaceInfo2KHR surface_info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
.surface = request.surface->vk_surface,
};
vk_result = vkGetPhysicalDeviceSurfaceFormats2KHR(request.device->physical_device.internal->vk_physical_device,
&surface_info, &surface_formats_count, NULL);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to query surface formats count");
VkSurfaceFormat2KHRArray format_pairs = wpArrayAllocCapacity(VkSurfaceFormat2KHR, temp,
surface_formats_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(format_pairs != NULL, &logger, "Failed to allocate temp format array");
for (u32 i = 0; i < surface_formats_count; ++i) {
format_pairs[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
}
vk_result = vkGetPhysicalDeviceSurfaceFormats2KHR(request.device->physical_device.internal->vk_physical_device,
&surface_info, &surface_formats_count, format_pairs);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get surface formats");
VkFormat requested_format = vkFormatFromGpuFormat(request.format);
VkColorSpaceKHR requested_colorspace = vkColorspaceFromGpuColorspace(request.colorspace);
b8 surface_format_supported = false;
for (u32 i = 0; i < surface_formats_count; ++i) {
if (requested_format == format_pairs[i].surfaceFormat.format &&
requested_colorspace == format_pairs[i].surfaceFormat.colorSpace) {
surface_format_supported = true;
break;
}
}
assertWithLogger(surface_format_supported, &logger, "Requested surface format not supported");
GpuSwapchain *swapchain = wpMemAllocatorAlloc(allocator, sizeof(GpuSwapchain));
assertWithLogger(swapchain != NULL, &logger, "Failed to allocate swapchain internal");
swapchain->extent = request.surface->capabilities.currentExtent;
// Handle Wayland's special value (0xffffffff), which indicate that the surface size will
// basically be determined by the size of the surface
if (swapchain->extent.width == 0xffffffff) {
swapchain->extent.width = (u32)request.surface->window->size.x;
swapchain->extent.height = (u32)request.surface->window->size.y;
}
u32 image_count = clamp(request.ideal_image_count,
request.surface->capabilities.minImageCount,
request.surface->capabilities.maxImageCount > 0 ?
request.surface->capabilities.maxImageCount :
request.ideal_image_count);
VkSwapchainCreateInfoKHR swapchain_create_info = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.surface = request.surface->vk_surface,
.minImageCount = image_count,
.imageFormat = requested_format,
.imageColorSpace = requested_colorspace,
.imageExtent = swapchain->extent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = vkPresentModeFromGpuPresentMode(request.present_mode),
};
vk_result = vkCreateSwapchainKHR(request.device->vk_device, &swapchain_create_info, NULL,
&swapchain->vk_swapchain);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan swapchain");
u32 swapchain_image_count = 0;
vk_result = vkGetSwapchainImagesKHR(request.device->vk_device, swapchain->vk_swapchain,
&swapchain_image_count, NULL);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to retrieve swapchain image count");
VkImageArray images = wpArrayAllocCapacity(VkImage, temp, swapchain_image_count, WP_ARRAY_INIT_FILLED);
swapchain->images = wpArrayAllocCapacity(GpuImage, allocator, swapchain_image_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(images != NULL && swapchain->images != NULL, &logger, "Failed to allocate swapchain images");
vk_result = vkGetSwapchainImagesKHR(request.device->vk_device, swapchain->vk_swapchain,
&swapchain_image_count, images);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to retrieve swapchain images");
for (u32 i = 0; i < swapchain_image_count; ++i) {
swapchain->images[i].vk_image = images[i];
swapchain->images[i].size = (ivec3s){ .x = swapchain->extent.width,
.y = swapchain->extent.height,
.z = 1 };
swapchain->images[i].format = vkFormatFromGpuFormat(request.format);
swapchain->images[i].device = request.device;
VkImageViewCreateInfo view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = swapchain->images[i].vk_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = requested_format,
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.subresourceRange.levelCount = 1,
.subresourceRange.layerCount = 1,
};
vk_result = vkCreateImageView(request.device->vk_device, &view_create_info, NULL,
&swapchain->images[i].vk_view);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create swapchain image view");
}
// NOTE (Abdelrahman): Favour 24-bit format for performance
VkFormat depth_format = VK_FORMAT_UNDEFINED;
VkFormatArray depth_formats = wpArray(VkFormat, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
for (u32 i = 0; i < wpArrayCount(depth_formats); ++i) {
VkFormatProperties2 format_properties = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 };
vkGetPhysicalDeviceFormatProperties2(request.device->physical_device.internal->vk_physical_device,
depth_formats[i], &format_properties);
if (format_properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
depth_format = depth_formats[i];
break;
}
}
assertWithLogger(depth_format != VK_FORMAT_UNDEFINED, &logger, "Failed to retrieve depth image format");
VkImageCreateInfo depth_image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = depth_format,
.extent = (VkExtent3D){ .width = swapchain->extent.width,
.height = swapchain->extent.height,
.depth = 1 },
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
VmaAllocationCreateInfo depth_alloc_create_info = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
vk_result = vmaCreateImage(request.device->allocator, &depth_image_create_info, &depth_alloc_create_info,
&swapchain->depth.vk_image, &swapchain->depth.allocation, NULL);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image");
VkImageViewCreateInfo depth_view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = swapchain->depth.vk_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = depth_format,
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.subresourceRange.levelCount = 1,
.subresourceRange.layerCount = 1,
};
vk_result = vkCreateImageView(request.device->vk_device, &depth_view_create_info, NULL,
&swapchain->depth.vk_view);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image view");
swapchain->depth.size = (ivec3s){ .x = swapchain->extent.width, .y = swapchain->extent.height, .z = 1 };
swapchain->depth.format = depth_format;
swapchain->depth.device = request.device;
swapchain->device = request.device;
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Created Vulkan swapchain %p", swapchain->vk_swapchain);
wpLogDebug(&logger, msg);
return swapchain;
}
void gpuDestroySwapchain(GpuSwapchain *swapchain) {
vkDestroyImageView(swapchain->device->vk_device, swapchain->depth.vk_view, NULL);
vmaDestroyImage(swapchain->device->allocator, swapchain->depth.vk_image, swapchain->depth.allocation);
if (swapchain->images) {
for (u64 i = 0; i < wpArrayCount(swapchain->images); ++i) {
vkDestroyImageView(swapchain->device->vk_device, swapchain->images[i].vk_view, NULL);
}
}
vkDestroySwapchainKHR(swapchain->device->vk_device, swapchain->vk_swapchain, NULL);
}
u64 gpuGetSwapchainImageCount(GpuSwapchain *swapchain) {
return wpArrayCount(swapchain->images);
}
GpuFormat gpuGetSwapchainImageFormat(GpuSwapchain *swapchain) {
return gpuFormatFromVkFormat(swapchain->images[0].format);
}
GpuFormat gpuGetSwapchainDepthFormat(GpuSwapchain *swapchain) {
return gpuFormatFromVkFormat(swapchain->depth.format);
}
GpuSampler *gpuCreateSampler(const WpAllocator *allocator, GpuSamplerCreateRequest request) {
GpuSampler *output = wpMemAllocatorAlloc(allocator, sizeof(GpuSampler));
assertWithLogger(output != NULL, &logger, "Failed to allocate sampler");
VkSamplerCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.magFilter = vkFilterFromGpuFilter(request.mag_filter),
.minFilter = vkFilterFromGpuFilter(request.min_filter),
.mipmapMode = vkSamplerMipmapModeFromGpuSamplerMipmapMode(request.mipmap_mode),
.addressModeU = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_u),
.addressModeV = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_v),
.addressModeW = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_w),
.anisotropyEnable = VK_TRUE,
.maxAnisotropy = 8.0f,
.maxLod = VK_LOD_CLAMP_NONE,
.compareEnable = request.compare_enable,
.compareOp = vkCompareOpFromGpuCompareOp(request.compare_op),
};
VkResult vk_result = vkCreateSampler(request.device->vk_device, &info, NULL, &output->vk_sampler);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan sampler");
wpLogDebug(&logger, wpStr8Lit("Created Vulkan sampler"));
return output;
}
void gpuDestroySampler(GpuSampler *sampler) {
vkDestroySampler(sampler->device->vk_device, sampler->vk_sampler, NULL);
}
GpuImage *gpuCreateImage(const WpAllocator *allocator, GpuImageCreateRequest request) {
VkResult vk_result = VK_SUCCESS;
GpuImage *output = wpMemAllocatorAlloc(allocator, sizeof(GpuImage));
assertWithLogger(output != NULL, &logger, "Failed to allocate image");
VkFormat format = vkFormatFromGpuFormat(request.format);
VkImageCreateInfo image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = vkImageTypeFromGpuImageType(request.type),
.format = format,
.extent = (VkExtent3D){ .width = request.size.x,
.height = request.size.y,
.depth = request.size.z },
.mipLevels = request.subresource.level_count,
.arrayLayers = request.subresource.layer_count,
.samples = vkSampleCountFromGpuSampleCount(request.samples),
.tiling = vkImageTilingFromGpuImageTiling(request.tiling),
.usage = vkImageUsageFromGpuImageUsage(request.usage),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index,
.initialLayout = vkImageLayoutFromGpuImageLayout(request.layout),
};
VmaAllocationCreateInfo alloc_create_info = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
vk_result = vmaCreateImage(request.device->allocator, &image_create_info, &alloc_create_info,
&output->vk_image, &output->allocation, NULL);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image");
VkImageViewCreateInfo view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = output->vk_image,
.viewType = vkImageViewTypeFromGpuImageType(request.type),
.format = vkFormatFromGpuFormat(request.format),
.subresourceRange.aspectMask = vkImageAspectFromGpuImageAspect(request.subresource.aspect),
.subresourceRange.levelCount = 1,
.subresourceRange.layerCount = 1,
};
vk_result = vkCreateImageView(request.device->vk_device, &view_create_info, NULL, &output->vk_view);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image view");
output->size = request.size;
output->format = format;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan image"));
return output;
}
void gpuDestroyImage(GpuImage *image) {
vkDestroyImageView(image->device->vk_device, image->vk_view, NULL);
vmaDestroyImage(image->device->allocator, image->vk_image, image->allocation);
}
ivec3s gpuImageGetSize(GpuImage *image) {
return image->size;
}
GpuBuffer gpuCreateBuffer(const WpAllocator *allocator, GpuBufferCreateRequest request) {
GpuBuffer buffer = {0};
VkResult vk_result = VK_SUCCESS;
buffer.internal = wpMemAllocatorAlloc(allocator, sizeof(GpuBufferInternal));
assertWithLogger(buffer.internal != NULL, &logger, "Failed to allocate buffer internal");
VkBufferUsageFlags2CreateInfo buf_usage_flags = {
.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO,
.usage = vkBufferUsageFromGpuBufferUsage(request.usage),
};
VkBufferCreateInfo buf_create_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = request.size,
.pNext = &buf_usage_flags,
};
VmaAllocationCreateInfo buf_alloc_create_info = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
vk_result = vmaCreateBuffer(request.device->allocator, &buf_create_info, &buf_alloc_create_info,
&buffer.internal->vk_buffer, &buffer.internal->allocation,
&buffer.internal->allocation_info);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create buffer");
if ((request.usage & GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) == GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) {
VkBufferDeviceAddressInfo buf_dev_addr_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = buffer.internal->vk_buffer,
};
buffer.gpu_device_address = vkGetBufferDeviceAddress(request.device->vk_device, &buf_dev_addr_info);
}
buffer.device = request.device;
buffer.cpu_mapping = buffer.internal->allocation_info.pMappedData;
buffer.size = buffer.internal->allocation_info.size;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan buffer"));
return buffer;
}
void gpuDestroyBuffer(GpuBuffer *buffer) {
vmaDestroyBuffer(buffer->device->allocator, buffer->internal->vk_buffer, buffer->internal->allocation);
buffer->device = NULL;
buffer->cpu_mapping = NULL;
buffer->gpu_device_address = 0;
buffer->size = 0;
}
GpuFence *gpuCreateFence(const WpAllocator *allocator, GpuDevice *device) {
GpuFence *fence = wpMemAllocatorAlloc(allocator, sizeof(GpuFence));
assertWithLogger(fence != NULL, &logger, "Failed to allocate fence internal");
VkFenceCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
VkResult vk_result = vkCreateFence(device->vk_device, &info, NULL, &fence->vk_fence);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create fence");
fence->device = device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan fence"));
return fence;
}
void gpuDestroyFence(GpuFence *fence) {
vkDestroyFence(fence->device->vk_device, fence->vk_fence, NULL);
}
void gpuResetFence(GpuFence *fence) {
VkResult vk_result = vkResetFences(fence->device->vk_device, 1, &fence->vk_fence);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset fence");
}
GpuSemaphore *gpuCreateSemaphore(const WpAllocator *allocator, GpuDevice *device) {
GpuSemaphore *semaphore = wpMemAllocatorAlloc(allocator, sizeof(GpuSemaphore));
assertWithLogger(semaphore != NULL, &logger, "Failed to allocate semaphore internal");
VkSemaphoreCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
VkResult vk_result = vkCreateSemaphore(device->vk_device, &info, NULL, &semaphore->vk_semaphore);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create semaphore");
semaphore->device = device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan semaphore"));
return semaphore;
}
void gpuDestroySemaphore(GpuSemaphore *semaphore) {
vkDestroySemaphore(semaphore->device->vk_device, semaphore->vk_semaphore, NULL);
}
GpuCommandPool *gpuCreateCommandPool(const WpAllocator *allocator, GpuDevice *device) {
GpuCommandPool *pool = wpMemAllocatorAlloc(allocator, sizeof(GpuCommandPool));
assertWithLogger(pool != NULL, &logger, "Failed to allocate pool internal");
VkCommandPoolCreateInfo pool_create_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = device->physical_device.internal->queue_family_index,
};
VkResult vk_result = vkCreateCommandPool(device->vk_device, &pool_create_info, NULL, &pool->vk_pool);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create command pool");
pool->device = device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan command pool"));
return pool;
}
void gpuDestroyCommandPool(GpuCommandPool *pool) {
vkDestroyCommandPool(pool->device->vk_device, pool->vk_pool, NULL);
}
void gpuResetCommandPool(GpuCommandPool *pool) {
VkResult vk_result = vkResetCommandPool(pool->device->vk_device, pool->vk_pool, 0);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset command pool");
}
GpuCommandBufferPtrArray gpuAllocateCommandBuffers(const WpAllocator *allocator, const WpAllocator *temp,
GpuCommandBufferAllocateRequest request) {
VkCommandBufferArray vk_buffers = wpArrayAllocCapacity(VkCommandBuffer, temp, request.buffer_count,
WP_ARRAY_INIT_FILLED);
GpuCommandBufferPtrArray buffers = wpArrayAllocCapacity(GpuCommandBuffer *, allocator, request.buffer_count,
WP_ARRAY_INIT_FILLED);
assertWithLogger(vk_buffers != NULL && buffers != NULL, &logger, "Failed to allocate command buffer arrays");
VkCommandBufferAllocateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = request.pool->vk_pool,
.commandBufferCount = request.buffer_count,
};
VkResult vk_result = vkAllocateCommandBuffers(request.pool->device->vk_device, &info, vk_buffers);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to allocate command buffers");
for (u64 i = 0; i < request.buffer_count; ++i) {
buffers[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuCommandBuffer));
assertWithLogger(buffers[i] != NULL, &logger, "Failed to allocate command buffer internal");
buffers[i]->pool = request.pool;
buffers[i]->vk_buffer = vk_buffers[i];
}
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Allocated %" PRIu32 " command buffers from pool %p", request.buffer_count, request.pool->vk_pool);
wpLogDebug(&logger, msg);
return buffers;
}
void gpuBeginCommandBuffer(GpuCommandBuffer *buffer) {
VkCommandBufferBeginInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
VkResult vk_result = vkBeginCommandBuffer(buffer->vk_buffer, &info);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to begin command buffer");
}
void gpuEndCommandBuffer(GpuCommandBuffer *buffer) {
VkResult vk_result = vkEndCommandBuffer(buffer->vk_buffer);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to end command buffer");
}
void gpuSubmitCommandBuffers(const WpAllocator *temp, GpuCommandBuffersSubmitRequest request) {
u64 buffer_count = wpArrayCount(request.buffers);
VkCommandBufferArray vk_buffers = wpArrayAllocCapacity(VkCommandBuffer, temp, buffer_count,
WP_ARRAY_INIT_FILLED);
assertWithLogger(vk_buffers != NULL, &logger, "Failed to allocate temp buffers");
for (u64 i = 0; i < buffer_count; ++i) {
vk_buffers[i] = request.buffers[i]->vk_buffer;
}
VkSubmitInfo info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.commandBufferCount = buffer_count,
.pCommandBuffers = vk_buffers,
};
VkResult vk_result = VK_SUCCESS;
gpuResetFence(request.fence);
vk_result = vkQueueSubmit(request.device->vk_queue, 1, &info, request.fence->vk_fence);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to submit command buffers");
vk_result = vkWaitForFences(request.device->vk_device, 1, &request.fence->vk_fence, VK_TRUE, UINT64_MAX);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to wait for fences");
}
void gpuResetCommandBuffer(GpuCommandBuffer *buffer) {
VkResult vk_result = vkResetCommandBuffer(buffer->vk_buffer, 0);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset command buffer");
}
GpuDescriptorPool *gpuCreateDescriptorPool(const WpAllocator *allocator, GpuDescriptorPoolCreateRequest request) {
GpuDescriptorPool *output = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorPool));
assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor pool internal");
VkDescriptorPoolSizeArray sizes = wpArrayWithCapacity(VkDescriptorPoolSize, GPU_DESCRIPTOR_TYPE_COUNT,
WP_ARRAY_INIT_NONE);
if (request.descriptor_pool_sizes != NULL) {
for (u64 i = 0; i < wpArrayCount(request.descriptor_pool_sizes); ++i) {
VkDescriptorPoolSize desc_pool_size = {
.type = vkDescriptorTypeFromGpuDescriptorType(request.descriptor_pool_sizes[i].type),
.descriptorCount = request.descriptor_pool_sizes[i].count,
};
wpArrayAppendCapped(VkDescriptorPoolSize, sizes, &desc_pool_size);
}
}
VkDescriptorPoolCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.maxSets = request.max_sets,
.poolSizeCount = wpArrayCount(sizes),
.pPoolSizes = sizes,
};
VkResult vk_result = vkCreateDescriptorPool(request.device->vk_device, &info, NULL, &output->vk_pool);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create descriptor pool");
output->device = request.device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan descriptor pool successfully"));
return output;
}
void gpuDestroyDescriptorPool(GpuDescriptorPool *pool) {
vkDestroyDescriptorPool(pool->device->vk_device, pool->vk_pool, NULL);
}
void gpuResetDescriptorPool(GpuDescriptorPool *pool) {
VkResult vk_result = vkResetDescriptorPool(pool->device->vk_device, pool->vk_pool, 0);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset descriptor pool");
}
GpuDescriptorSetLayout *gpuCreateDescriptorSetLayout(const WpAllocator *allocator, const WpAllocator *temp,
GpuDescriptorSetLayoutCreateRequest request) {
GpuDescriptorSetLayout *output = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorSetLayout));
assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor set layout internal");
output->variable_descriptor_count = 0;
u64 bindings_count = wpArrayCount(request.bindings);
VkDescriptorSetLayoutBindingArray vk_bindings = wpArrayAllocCapacity(VkDescriptorSetLayoutBinding, temp,
bindings_count, WP_ARRAY_INIT_NONE);
VkDescriptorBindingFlagsArray vk_binding_flags = wpArrayAllocCapacity(VkDescriptorBindingFlags, temp,
bindings_count, WP_ARRAY_INIT_NONE);
assertWithLogger(vk_bindings != NULL && vk_binding_flags != NULL, &logger,
"Failed to allocate temp descriptor set bindings and flags");
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = bindings_count,
.pBindingFlags = vk_binding_flags,
};
for (u64 i = 0; i < bindings_count; ++i) {
GpuDescriptorSetBinding *binding = &request.bindings[i];
b32 has_variable_count = binding->variable_count;
b32 is_last_binding = (i + 1) == bindings_count;
VkDescriptorBindingFlags binding_flags = 0;
if (has_variable_count) {
assertWithLogger(is_last_binding, &logger, "Binding has variable count but it's not the last binding");
binding_flags |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
output->variable_descriptor_count = binding->descriptor_count;
}
wpArrayAppendCapped(VkDescriptorBindingFlags, vk_binding_flags, &binding_flags);
VkDescriptorSetLayoutBinding vk_binding = {
.binding = binding->binding,
.descriptorType = vkDescriptorTypeFromGpuDescriptorType(binding->type),
.descriptorCount = binding->descriptor_count,
.stageFlags = vkShaderStageFromGpuShaderStage(binding->stages),
};
wpArrayAppendCapped(VkDescriptorSetLayoutBinding, vk_bindings, &vk_binding);
}
VkDescriptorSetLayoutCreateInfo layout_create_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &binding_flags_info,
.bindingCount = wpArrayCount(vk_bindings),
.pBindings = vk_bindings,
};
VkResult vk_result = vkCreateDescriptorSetLayout(request.device->vk_device, &layout_create_info, NULL,
&output->vk_layout);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create descriptor set layout");
output->device = request.device;
wpLogDebug(&logger, wpStr8Lit("Created descriptor set layout successfully"));
return output;
}
void gpuDestroyDescriptorSetLayout(GpuDescriptorSetLayout *layout) {
vkDestroyDescriptorSetLayout(layout->device->vk_device, layout->vk_layout, NULL);
}
GpuDescriptorSetPtrArray gpuAllocateDescriptorSets(const WpAllocator *allocator, const WpAllocator *temp,
GpuDescriptorSetAllocateRequest request) {
VkResult vk_result = VK_SUCCESS;
u64 set_count = wpArrayCount(request.layouts);
GpuDescriptorSetPtrArray output = wpArrayAllocCapacity(GpuDescriptorSet *, allocator, set_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor set array");
VkDescriptorSetLayoutArray vk_layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, temp, set_count,
WP_ARRAY_INIT_FILLED);
VkDescriptorSetVariableDescriptorCountAllocateInfoArray vk_var_alloc_infos =
wpArrayAllocCapacity(VkDescriptorSetVariableDescriptorCountAllocateInfo, temp, set_count, WP_ARRAY_INIT_FILLED);
VkDescriptorSetArray vk_sets = wpArrayAllocCapacity(VkDescriptorSet, temp, set_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(vk_layouts != NULL && vk_sets != NULL, &logger, "Failed to allocate temp sets and layouts");
for (u64 i = 0; i < set_count; ++i) {
output[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorSet));
assertWithLogger(output[i] != NULL, &logger, "Failed to allocator descriptor set internal");
vk_var_alloc_infos[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
if (request.layouts[i]->variable_descriptor_count > 0) {
vk_var_alloc_infos[i].descriptorSetCount = 1;
vk_var_alloc_infos[i].pDescriptorCounts = &(request.layouts[i]->variable_descriptor_count);
}
vk_layouts[i] = request.layouts[i]->vk_layout;
}
VkDescriptorSetAllocateInfo set_alloc_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = vk_var_alloc_infos,
.descriptorPool = request.pool->vk_pool,
.descriptorSetCount = set_count,
.pSetLayouts = vk_layouts,
};
vk_result = vkAllocateDescriptorSets(request.pool->device->vk_device, &set_alloc_info, vk_sets);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to allocate descriptor sets");
for (u64 i = 0; i < set_count; ++i) {
output[i]->pool = request.pool;
output[i]->layout = request.layouts[i];
output[i]->vk_set = vk_sets[i];
}
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Allocated %" PRIu64 " descriptor set(s) successfully", set_count);
wpLogDebug(&logger, msg);
return output;
}
void gpuWriteDescriptorSets(const WpAllocator *temp, GpuDescriptorSetWriteRequest request) {
u64 info_count = wpArrayCount(request.write_infos);
u64 image_info_count = 0;
u64 buffer_info_count = 0;
for (u64 i = 0; i < info_count; ++i) {
GpuDescriptorSetWriteInfo *info = &request.write_infos[i];
image_info_count += info->image_infos != NULL ? wpArrayCount(info->image_infos) : 0;
buffer_info_count += info->buffer_infos != NULL ? wpArrayCount(info->buffer_infos) : 0;
}
VkWriteDescriptorSetArray vk_desc_set_writes = wpArrayAllocCapacity(VkWriteDescriptorSet, temp,
info_count, WP_ARRAY_INIT_NONE);
assertWithLogger(vk_desc_set_writes != NULL, &logger, "Failed to allocate temp writes array");
VkDescriptorImageInfoArray vk_desc_img_infos = NULL;
if (image_info_count > 0) {
vk_desc_img_infos = wpArrayAllocCapacity(VkDescriptorImageInfo, temp, image_info_count,
WP_ARRAY_INIT_NONE);
assertWithLogger(vk_desc_img_infos != NULL, &logger, "Failed to allocate temp image info array");
}
VkDescriptorBufferInfoArray vk_desc_buf_infos = NULL;
if (buffer_info_count > 0) {
vk_desc_buf_infos = wpArrayAllocCapacity(VkDescriptorBufferInfo, temp, buffer_info_count,
WP_ARRAY_INIT_NONE);
assertWithLogger(vk_desc_buf_infos != NULL, &logger, "Failed to allocate temp buffer info array");
}
u64 image_info_offset = 0;
u64 buffer_info_offset = 0;
for (u64 i = 0; i < info_count; ++i) {
GpuDescriptorSetWriteInfo *info = &request.write_infos[i];
VkWriteDescriptorSet desc_set_write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = info->set->vk_set,
.dstBinding = info->dst_binding,
.dstArrayElement = info->dst_array_element,
.descriptorType = vkDescriptorTypeFromGpuDescriptorType(info->descriptor_type),
};
GpuDescriptorCategory category = descriptorCategoryFromDescriptorType(info->descriptor_type);
switch (category) {
case GPU_DESCRIPTOR_CATEGORY_IMAGE: {
assertWithLogger(info->image_infos != NULL, &logger, "No image info provided for an image descriptor");
image_info_offset += retrieveDescriptorImageInfos(info, &desc_set_write, vk_desc_img_infos,
image_info_offset);
} break;
case GPU_DESCRIPTOR_CATEGORY_BUFFER: {
assertWithLogger(info->buffer_infos != NULL, &logger, "No buffer info provided for a buffer descriptor");
buffer_info_offset += retrieveDescriptorBufferInfos(info, &desc_set_write, vk_desc_buf_infos,
buffer_info_offset);
} break;
case GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER:
case GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK:
// TODO (Abdelrahman): Handle these cases
assertWithLogger(0, &logger, "Texel buffer and uniform block descriptors are not yet supported");
}
wpArrayAppendCapped(VkWriteDescriptorSet, vk_desc_set_writes, &desc_set_write);
}
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Wrote to %" PRIu64 " descriptor set(s) successfully", info_count);
wpLogDebug(&logger, msg);
vkUpdateDescriptorSets(request.device->vk_device, wpArrayCount(vk_desc_set_writes), vk_desc_set_writes,
0, NULL);
}
GpuShader *gpuCreateShader(const WpAllocator *allocator, GpuShaderCreateRequest request) {
GpuShader *output = wpMemAllocatorAlloc(allocator, sizeof(GpuShader));
assertWithLogger(output != NULL, &logger, "Failed to allocate shader internal");
VkShaderModuleCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = request.size,
.pCode = (u32 *)request.code,
};
VkResult vk_result = vkCreateShaderModule(request.device->vk_device, &info, NULL, &output->vk_shader);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan shader module");
output->device = request.device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan shader module successfully"));
return output;
}
void gpuDestroyShader(GpuShader *shader) {
vkDestroyShaderModule(shader->device->vk_device, shader->vk_shader, NULL);
}
GpuPipelineLayout *gpuCreatePipelineLayout(const WpAllocator *allocator, const WpAllocator *temp,
GpuPipelineLayoutCreateRequest request) {
GpuPipelineLayout *output = wpMemAllocatorAlloc(allocator, sizeof(GpuPipelineLayout));
assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline layout internal");
u64 layout_count = wpArrayCount(request.descriptor_set_layouts);
u64 push_constant_count = wpArrayCount(request.push_constants);
VkDescriptorSetLayoutArray layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, temp,
layout_count, WP_ARRAY_INIT_FILLED);
VkPushConstantRangeArray push_constants = wpArrayAllocCapacity(VkPushConstantRange, temp,
push_constant_count, WP_ARRAY_INIT_FILLED);
for (u64 i = 0; i < layout_count; ++i) {
layouts[i] = request.descriptor_set_layouts[i]->vk_layout;
}
for (u64 i = 0; i < push_constant_count; ++i) {
push_constants[i].stageFlags = vkShaderStageFromGpuShaderStage(request.push_constants[i].stages);
push_constants[i].offset = request.push_constants[i].offset;
push_constants[i].size = request.push_constants[i].size;
}
VkPipelineLayoutCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = wpArrayCount(layouts),
.pSetLayouts = layouts,
.pushConstantRangeCount = wpArrayCount(push_constants),
.pPushConstantRanges = push_constants,
};
VkResult vk_result = vkCreatePipelineLayout(request.device->vk_device, &info, NULL, &output->vk_layout);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan pipeline layout");
output->device = request.device;
wpLogDebug(&logger, wpStr8Lit("Created Vulkan pipeline layout successfully"));
return output;
}
void gpuDestroyPipelineLayout(GpuPipelineLayout *layout) {
vkDestroyPipelineLayout(layout->device->vk_device, layout->vk_layout, NULL);
}
GpuPipelinePtrArray gpuCreateGraphicsPipelines(const WpAllocator *allocator, const WpAllocator *temp,
GpuGraphicsPipelinesCreateRequest request) {
u64 pipeline_count = wpArrayCount(request.infos);
GpuPipelinePtrArray output = wpArrayAllocCapacity(GpuPipeline *, allocator, pipeline_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline internals");
VkGraphicsPipelineCreateInfoArray infos = wpArrayAllocCapacity(VkGraphicsPipelineCreateInfo, temp,
pipeline_count, WP_ARRAY_INIT_NONE);
assertWithLogger(infos != NULL, &logger, "Failed to allocate pipeline create infos");
VkPipelineArray pipelines = wpArrayAllocCapacity(VkPipeline, temp, pipeline_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(infos != NULL, &logger, "Failed to allocate temp pipelines");
GraphicsPipelinesTempArrays temp_arrays = allocateGraphicsPipelinesTempArrays(temp, request);
VkDynamicStateArray dynamic_states = wpArray(VkDynamicState, VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR);
VkPipelineDynamicStateCreateInfo dynamic_state_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = wpArrayCount(dynamic_states),
.pDynamicStates = dynamic_states,
};
for (u64 i = 0; i < pipeline_count; ++i) {
GpuGraphicsPipelineCreateInfo *info = &request.infos[i];
u64 shader_stages_count = wpArrayCount(info->shader_stages);
for (u64 j = 0; j < shader_stages_count; ++j) {
u64 idx = j + temp_arrays.shader_stages_offset;
temp_arrays.shader_stages[idx] = (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = vkShaderStageFromGpuShaderStage(info->shader_stages[j].stage),
.module = info->shader_stages[j].shader->vk_shader,
.pName = info->shader_stages[j].name,
};
}
u64 vert_input_bindings_count = wpArrayCount(info->vertex_input_state.bindings);
for (u64 j = 0; j < vert_input_bindings_count; ++j) {
u64 idx = j + temp_arrays.vertex_bindings_offset;
temp_arrays.vertex_bindings[idx] = (VkVertexInputBindingDescription){
.binding = info->vertex_input_state.bindings[j].binding,
.stride = info->vertex_input_state.bindings[j].stride,
.inputRate = vkVertexInputRateFromGpuVertexInputRate(info->vertex_input_state.bindings[j].input_rate),
};
}
u64 vert_input_attributes_count = wpArrayCount(info->vertex_input_state.attributes);
for (u64 j = 0; j < vert_input_attributes_count; ++j) {
u64 idx = j + temp_arrays.vertex_attributes_offset;
temp_arrays.vertex_attributes[idx] = (VkVertexInputAttributeDescription){
.location = info->vertex_input_state.attributes[j].location,
.binding = info->vertex_input_state.attributes[j].binding,
.offset = info->vertex_input_state.attributes[j].offset,
.format = vkFormatFromGpuFormat(info->vertex_input_state.attributes[j].format),
};
}
u64 blend_attachments_count = wpArrayCount(info->color_blend_state.attachments);
for (u64 j = 0; j < blend_attachments_count; ++j) {
u64 idx = j + temp_arrays.color_blend_attachments_offset;
temp_arrays.color_blend_attachments[idx] = (VkPipelineColorBlendAttachmentState){
.blendEnable = info->color_blend_state.attachments[j].blend_enable,
.srcColorBlendFactor = vkBlendFactorFromGpuBlendFactor(info->color_blend_state.attachments[j].src_color_blend_factor),
.dstColorBlendFactor = vkBlendFactorFromGpuBlendFactor(info->color_blend_state.attachments[j].dst_color_blend_factor),
.colorBlendOp = vkBlendOpFromGpuBlendOp(info->color_blend_state.attachments[j].color_blend_op),
.srcAlphaBlendFactor = vkBlendFactorFromGpuBlendFactor(info->color_blend_state.attachments[j].src_alpha_blend_factor),
.dstAlphaBlendFactor = vkBlendFactorFromGpuBlendFactor(info->color_blend_state.attachments[j].dst_alpha_blend_factor),
.alphaBlendOp = vkBlendOpFromGpuBlendOp(info->color_blend_state.attachments[j].alpha_blend_op),
.colorWriteMask = vkColorComponentFlagsFromGpuColorComponentFlags(info->color_blend_state.attachments[j].color_write_mask),
};
}
// States
temp_arrays.vertex_input_states[i] = (VkPipelineVertexInputStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = vert_input_bindings_count,
.pVertexBindingDescriptions = &temp_arrays.vertex_bindings[temp_arrays.vertex_bindings_offset],
.vertexAttributeDescriptionCount = vert_input_attributes_count,
.pVertexAttributeDescriptions = &temp_arrays.vertex_attributes[temp_arrays.vertex_attributes_offset],
};
temp_arrays.input_assembly_states[i] = (VkPipelineInputAssemblyStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = vkPrimitiveTopologyFromGpuPrimitiveTopology(info->input_assembly_state.topology),
};
temp_arrays.tesselation_states[i] = (VkPipelineTessellationStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
.patchControlPoints = info->tesselation_state.patch_control_points,
};
temp_arrays.viewport_states[i] = (VkPipelineViewportStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.viewportCount = info->viewport_state.viewport_count,
.scissorCount = info->viewport_state.scissor_count,
};
temp_arrays.rasterization_states[i] = (VkPipelineRasterizationStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.depthClampEnable = info->rasterization_state.depth_clamp_enable,
.rasterizerDiscardEnable = info->rasterization_state.rasterizer_discard_enable,
.polygonMode = vkPolygonModeFromGpuPolygonMode(info->rasterization_state.polygon_mode),
.cullMode = vkCullModeFromGpuCullMode(info->rasterization_state.cull_mode),
.frontFace = vkFrontFaceFromGpuFrontFace(info->rasterization_state.front_face),
.depthBiasEnable = info->rasterization_state.depth_bias_enable,
.depthBiasConstantFactor = info->rasterization_state.depth_bias_constant_factor,
.depthBiasClamp = info->rasterization_state.depth_bias_clamp,
.depthBiasSlopeFactor = info->rasterization_state.depth_bias_slope_factor,
.lineWidth = info->rasterization_state.line_width,
};
temp_arrays.multisample_states[i] = (VkPipelineMultisampleStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.rasterizationSamples = vkSampleCountFromGpuSampleCount(info->multisample_state.rasterization_samples),
.sampleShadingEnable = info->multisample_state.sample_shading_enable,
.minSampleShading = info->multisample_state.min_sample_shading,
};
temp_arrays.depth_stencil_states[i] = (VkPipelineDepthStencilStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.depthTestEnable = info->depth_stencil_state.depth_test_enable,
.depthWriteEnable = info->depth_stencil_state.depth_write_enable,
.depthCompareOp = vkCompareOpFromGpuCompareOp(info->depth_stencil_state.depth_compare_op),
.depthBoundsTestEnable = info->depth_stencil_state.depth_bounds_test_enable,
.stencilTestEnable = info->depth_stencil_state.stencil_test_enable,
.front = (VkStencilOpState){
.failOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.front.fail_op),
.passOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.front.pass_op),
.depthFailOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.front.depthFail_op),
.compareOp = vkCompareOpFromGpuCompareOp(info->depth_stencil_state.front.compare_op),
.compareMask = info->depth_stencil_state.front.compare_mask,
.writeMask = info->depth_stencil_state.front.write_mask,
.reference = info->depth_stencil_state.front.reference,
},
.back = (VkStencilOpState){
.failOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.back.fail_op),
.passOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.back.pass_op),
.depthFailOp = vkStencilOpFromGpuStencil(info->depth_stencil_state.back.depthFail_op),
.compareOp = vkCompareOpFromGpuCompareOp(info->depth_stencil_state.back.compare_op),
.compareMask = info->depth_stencil_state.back.compare_mask,
.writeMask = info->depth_stencil_state.back.write_mask,
.reference = info->depth_stencil_state.back.reference,
},
.minDepthBounds = info->depth_stencil_state.min_depth_bounds,
.maxDepthBounds = info->depth_stencil_state.max_depth_bounds,
};
temp_arrays.color_blend_states[i] = (VkPipelineColorBlendStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.logicOpEnable = info->color_blend_state.logic_op_enable,
.logicOp = vkLogicOpFromGpuLogicOp(info->color_blend_state.logic_op),
.attachmentCount = blend_attachments_count,
.pAttachments = &temp_arrays.color_blend_attachments[temp_arrays.color_blend_attachments_offset],
.blendConstants = {
[0] = info->color_blend_state.blend_constants[0],
[1] = info->color_blend_state.blend_constants[1],
[2] = info->color_blend_state.blend_constants[2],
[3] = info->color_blend_state.blend_constants[3],
},
};
temp_arrays.color_attachment_formats[i] = vkFormatFromGpuFormat(info->color_attachment_format);
temp_arrays.dynamic_rendering_infos[i] = (VkPipelineRenderingCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
.colorAttachmentCount = 1,
.pColorAttachmentFormats = &temp_arrays.color_attachment_formats[i],
.depthAttachmentFormat = vkFormatFromGpuFormat(info->depth_attachment_format),
};
VkGraphicsPipelineCreateInfo vk_info = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &temp_arrays.dynamic_rendering_infos[i],
.stageCount = shader_stages_count,
.pStages = &temp_arrays.shader_stages[temp_arrays.shader_stages_offset],
.pVertexInputState = &temp_arrays.vertex_input_states[i],
.pInputAssemblyState = &temp_arrays.input_assembly_states[i],
.pTessellationState = &temp_arrays.tesselation_states[i],
.pViewportState = &temp_arrays.viewport_states[i],
.pRasterizationState = &temp_arrays.rasterization_states[i],
.pMultisampleState = &temp_arrays.multisample_states[i],
.pDepthStencilState = &temp_arrays.depth_stencil_states[i],
.pColorBlendState = &temp_arrays.color_blend_states[i],
.pDynamicState = &dynamic_state_info,
.layout = info->layout->vk_layout,
};
temp_arrays.shader_stages_offset += shader_stages_count;
temp_arrays.vertex_bindings_offset += vert_input_bindings_count;
temp_arrays.vertex_attributes_offset += vert_input_attributes_count;
temp_arrays.color_blend_attachments_offset += blend_attachments_count;
wpArrayAppendCapped(VkGraphicsPipelineCreateInfo, infos, &vk_info);
}
u64 infos_count = wpArrayCount(infos);
// TODO (Abdelrahman): Create pipeline cache
VkResult vk_result = vkCreateGraphicsPipelines(request.device->vk_device, VK_NULL_HANDLE,
infos_count, infos, NULL, pipelines);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan graphics pipelines");
for (u64 i = 0; i < infos_count; ++i) {
output[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuPipeline));
assertWithLogger(output[i] != NULL, &logger, "Failed to allocate pipeline internal");
output[i]->layout = request.infos[i].layout;
output[i]->vk_pipeline = pipelines[i];
}
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Created %" PRIu64 " graphics pipeline(s) successfully", infos_count);
wpLogDebug(&logger, msg);
return output;
}
GpuPipelinePtrArray gpuCreateComputePipelines(const WpAllocator *allocator, const WpAllocator *temp,
GpuComputePipelinesCreateRequest request) {
u64 pipeline_count = wpArrayCount(request.infos);
GpuPipelinePtrArray output = wpArrayAllocCapacity(GpuPipeline *, allocator, pipeline_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline array");
VkComputePipelineCreateInfoArray infos = wpArrayAllocCapacity(VkComputePipelineCreateInfo, temp,
pipeline_count, WP_ARRAY_INIT_NONE);
assertWithLogger(infos != NULL, &logger, "Failed to allocate pipeline create infos");
VkPipelineArray pipelines = wpArrayAllocCapacity(VkPipeline, temp, pipeline_count, WP_ARRAY_INIT_FILLED);
assertWithLogger(infos != NULL, &logger, "Failed to allocate temp pipelines");
for (u64 i = 0; i < pipeline_count; ++i) {
VkComputePipelineCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.stage = (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = vkShaderStageFromGpuShaderStage(request.infos[i].shader_stage.stage),
.module = request.infos[i].shader_stage.shader->vk_shader,
.pName = request.infos[i].shader_stage.name,
},
.layout = request.infos[i].layout->vk_layout,
};
wpArrayAppendCapped(VkComputePipelineCreateInfo, infos, &info);
}
u64 infos_count = wpArrayCount(infos);
// TODO (Abdelrahman): Create pipeline cache
VkResult vk_result = vkCreateComputePipelines(request.device->vk_device, VK_NULL_HANDLE,
infos_count, infos, NULL, pipelines);
assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan compute pipelines");
for (u64 i = 0; i < infos_count; ++i) {
output[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuPipeline));
assertWithLogger(output[i] != NULL, &logger, "Failed to allocate pipeline internal");
output[i]->layout = request.infos[i].layout;
output[i]->vk_pipeline = pipelines[i];
}
WpStr8 msg = wpStr8Buf(4096);
wpStr8Format(&msg, "Created %" PRIu64 " compute pipeline(s) successfully", infos_count);
wpLogDebug(&logger, msg);
return output;
}
void gpuDestroyPipeline(GpuPipeline *pipeline) {
vkDestroyPipeline(pipeline->layout->device->vk_device, pipeline->vk_pipeline, NULL);
}
void gpuDeviceWaitIdle(GpuDevice *device) {
vkDeviceWaitIdle(device->vk_device);
}
wp_intern VkExtensions getInstanceExtensions(void) {
Config config = configGet();
VkExtensions output = {0};
switch (config.window_backend) {
case WINDOW_BACKEND_SDL: {
output.extensions = SDL_Vulkan_GetInstanceExtensions(&output.count);
} break;
default: break;
}
return output;
}
wp_intern GpuPhysicalDeviceType vkDeviceTypeToGpuDeviceType(VkPhysicalDeviceType type) {
switch (type) {
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU;
case VK_PHYSICAL_DEVICE_TYPE_CPU: return GPU_PHYSICAL_DEVICE_TYPE_CPU;
default: return GPU_PHYSICAL_DEVICE_TYPE_UNKNOWN;
}
}
wp_intern VkPhysicalDeviceType gpuDeviceTypeToVkDeviceType(GpuPhysicalDeviceType type) {
switch (type) {
case GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
case GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
case GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU;
case GPU_PHYSICAL_DEVICE_TYPE_CPU: return VK_PHYSICAL_DEVICE_TYPE_CPU;
default: return VK_PHYSICAL_DEVICE_TYPE_OTHER;
}
}
wp_intern i32 findQueueFamily(const WpAllocator *allocator, VkInstance instance,
VkPhysicalDevice physical_device, GpuPhysicalDeviceOps ops) {
i32 queue_family_index = -1;
u32 queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_count, NULL);
if (queue_family_count == 0) { goto FIND_QUEUE_FAMILY_RETURN; }
VkQueueFamilyProperties2Array queue_family_properties =
wpArrayAllocCapacity(VkQueueFamilyProperties2, allocator, queue_family_count, WP_ARRAY_INIT_FILLED);
if (!queue_family_properties) { goto FIND_QUEUE_FAMILY_RETURN; }
for (u32 i = 0; i < queue_family_count; ++i) {
queue_family_properties[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
}
vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_count, queue_family_properties);
VkQueueFlags requested_flags = queueFlagsFromOps(ops);
b8 presentation_requested = (ops & GPU_PHYSICAL_DEVICE_OP_PRESENTATION) == GPU_PHYSICAL_DEVICE_OP_PRESENTATION;
for (u32 i = 0; i < queue_family_count; ++i) {
VkQueueFlags queue_flags = queue_family_properties[i].queueFamilyProperties.queueFlags;
b8 presentation_supported = presentationSupported(instance, physical_device, i);
b8 ops_supported = (queue_flags & requested_flags) == requested_flags;
if (ops_supported && (!presentation_requested || presentation_supported)) {
queue_family_index = i;
break;
}
}
FIND_QUEUE_FAMILY_RETURN:
return queue_family_index;
}
wp_intern VkQueueFlags queueFlagsFromOps(GpuPhysicalDeviceOps ops) {
VkQueueFlags flags = 0;
flags |= (ops & GPU_PHYSICAL_DEVICE_OP_GRAPHICS) != 0 ? VK_QUEUE_GRAPHICS_BIT : 0;
flags |= (ops & GPU_PHYSICAL_DEVICE_OP_COMPUTE) != 0 ? VK_QUEUE_COMPUTE_BIT : 0;
flags |= (ops & GPU_PHYSICAL_DEVICE_OP_TRANSFER) != 0 ? VK_QUEUE_TRANSFER_BIT : 0;
flags |= (ops & GPU_PHYSICAL_DEVICE_OP_VIDEO_DECODE) != 0 ? VK_QUEUE_VIDEO_DECODE_BIT_KHR : 0;
flags |= (ops & GPU_PHYSICAL_DEVICE_OP_VIDEO_ENCODE) != 0 ? VK_QUEUE_VIDEO_ENCODE_BIT_KHR : 0;
return flags;
}
wp_intern b8 presentationSupported(VkInstance instance, VkPhysicalDevice device, u32 queue_family_index) {
Config config = configGet();
switch (config.window_backend) {
case WINDOW_BACKEND_SDL: return SDL_Vulkan_GetPresentationSupport(instance, device, queue_family_index);
default: return false;
}
}
wp_intern b8 windowBackendCreateSurface(const Window *window, VkInstance instance, VkSurfaceKHR *surface) {
Config config = configGet();
switch (config.window_backend) {
case WINDOW_BACKEND_SDL: return SDL_Vulkan_CreateSurface((SDL_Window *)window->internal.window,
instance, NULL, surface);
default: return false;
}
}
wp_intern VkFormat vkFormatFromGpuFormat(GpuFormat format) {
switch (format) {
case GPU_FORMAT_R8_UINT: return VK_FORMAT_R8_UINT;
case GPU_FORMAT_R8_SINT: return VK_FORMAT_R8_SINT;
case GPU_FORMAT_R8_SRGB: return VK_FORMAT_R8_SRGB;
case GPU_FORMAT_R8G8_UINT: return VK_FORMAT_R8G8_UINT;
case GPU_FORMAT_R8G8_SINT: return VK_FORMAT_R8G8_SINT;
case GPU_FORMAT_R8G8_SRGB: return VK_FORMAT_R8G8_SRGB;
case GPU_FORMAT_R8G8B8_UINT: return VK_FORMAT_R8G8B8_UINT;
case GPU_FORMAT_R8G8B8_SINT: return VK_FORMAT_R8G8B8_SINT;
case GPU_FORMAT_R8G8B8_SRGB: return VK_FORMAT_R8G8B8_SRGB;
case GPU_FORMAT_B8G8R8_UINT: return VK_FORMAT_B8G8R8_UINT;
case GPU_FORMAT_B8G8R8_SINT: return VK_FORMAT_B8G8R8_SINT;
case GPU_FORMAT_B8G8R8_SRGB: return VK_FORMAT_B8G8R8_SRGB;
case GPU_FORMAT_R8G8B8A8_UINT: return VK_FORMAT_R8G8B8A8_UINT;
case GPU_FORMAT_R8G8B8A8_SINT: return VK_FORMAT_R8G8B8A8_SINT;
case GPU_FORMAT_R8G8B8A8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
case GPU_FORMAT_B8G8R8A8_UINT: return VK_FORMAT_B8G8R8A8_UINT;
case GPU_FORMAT_B8G8R8A8_SINT: return VK_FORMAT_B8G8R8A8_SINT;
case GPU_FORMAT_B8G8R8A8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
case GPU_FORMAT_R16_UINT: return VK_FORMAT_R16_UINT;
case GPU_FORMAT_R16_SINT: return VK_FORMAT_R16_SINT;
case GPU_FORMAT_R16_SFLOAT: return VK_FORMAT_R16_SFLOAT;
case GPU_FORMAT_R16G16_UINT: return VK_FORMAT_R16G16_UINT;
case GPU_FORMAT_R16G16_SINT: return VK_FORMAT_R16G16_SINT;
case GPU_FORMAT_R16G16_SFLOAT: return VK_FORMAT_R16G16_SFLOAT;
case GPU_FORMAT_R16G16B16_UINT: return VK_FORMAT_R16G16B16_UINT;
case GPU_FORMAT_R16G16B16_SINT: return VK_FORMAT_R16G16B16_SINT;
case GPU_FORMAT_R16G16B16_SFLOAT: return VK_FORMAT_R16G16B16_SFLOAT;
case GPU_FORMAT_R16G16B16A16_UINT: return VK_FORMAT_R16G16B16A16_UINT;
case GPU_FORMAT_R16G16B16A16_SINT: return VK_FORMAT_R16G16B16A16_SINT;
case GPU_FORMAT_R16G16B16A16_SFLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT;
case GPU_FORMAT_R32_UINT: return VK_FORMAT_R32_UINT;
case GPU_FORMAT_R32_SINT: return VK_FORMAT_R32_SINT;
case GPU_FORMAT_R32_SFLOAT: return VK_FORMAT_R32_SFLOAT;
case GPU_FORMAT_R32G32_UINT: return VK_FORMAT_R32G32_UINT;
case GPU_FORMAT_R32G32_SINT: return VK_FORMAT_R32G32_SINT;
case GPU_FORMAT_R32G32_SFLOAT: return VK_FORMAT_R32G32_SFLOAT;
case GPU_FORMAT_R32G32B32_UINT: return VK_FORMAT_R32G32B32_UINT;
case GPU_FORMAT_R32G32B32_SINT: return VK_FORMAT_R32G32B32_SINT;
case GPU_FORMAT_R32G32B32_SFLOAT: return VK_FORMAT_R32G32B32_SFLOAT;
case GPU_FORMAT_R32G32B32A32_UINT: return VK_FORMAT_R32G32B32A32_UINT;
case GPU_FORMAT_R32G32B32A32_SINT: return VK_FORMAT_R32G32B32A32_SINT;
case GPU_FORMAT_R32G32B32A32_SFLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT;
case GPU_FORMAT_R64_UINT: return VK_FORMAT_R64_UINT;
case GPU_FORMAT_R64_SINT: return VK_FORMAT_R64_SINT;
case GPU_FORMAT_R64_SFLOAT: return VK_FORMAT_R64_SFLOAT;
case GPU_FORMAT_R64G64_UINT: return VK_FORMAT_R64G64_UINT;
case GPU_FORMAT_R64G64_SINT: return VK_FORMAT_R64G64_SINT;
case GPU_FORMAT_R64G64_SFLOAT: return VK_FORMAT_R64G64_SFLOAT;
case GPU_FORMAT_R64G64B64_UINT: return VK_FORMAT_R64G64B64_UINT;
case GPU_FORMAT_R64G64B64_SINT: return VK_FORMAT_R64G64B64_SINT;
case GPU_FORMAT_R64G64B64_SFLOAT: return VK_FORMAT_R64G64B64_SFLOAT;
case GPU_FORMAT_R64G64B64A64_UINT: return VK_FORMAT_R64G64B64A64_UINT;
case GPU_FORMAT_R64G64B64A64_SINT: return VK_FORMAT_R64G64B64A64_SINT;
case GPU_FORMAT_R64G64B64A64_SFLOAT: return VK_FORMAT_R64G64B64A64_SFLOAT;
case GPU_FORMAT_D24_UNORM_S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT;
case GPU_FORMAT_D32_SFLOAT_S8_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT;
default: return VK_FORMAT_UNDEFINED;
}
}
wp_intern GpuFormat gpuFormatFromVkFormat(VkFormat format) {
switch (format) {
case VK_FORMAT_R8_UINT: return GPU_FORMAT_R8_UINT;
case VK_FORMAT_R8_SINT: return GPU_FORMAT_R8_SINT;
case VK_FORMAT_R8_SRGB: return GPU_FORMAT_R8_SRGB;
case VK_FORMAT_R8G8_UINT: return GPU_FORMAT_R8G8_UINT;
case VK_FORMAT_R8G8_SINT: return GPU_FORMAT_R8G8_SINT;
case VK_FORMAT_R8G8_SRGB: return GPU_FORMAT_R8G8_SRGB;
case VK_FORMAT_R8G8B8_UINT: return GPU_FORMAT_R8G8B8_UINT;
case VK_FORMAT_R8G8B8_SINT: return GPU_FORMAT_R8G8B8_SINT;
case VK_FORMAT_R8G8B8_SRGB: return GPU_FORMAT_R8G8B8_SRGB;
case VK_FORMAT_B8G8R8_UINT: return GPU_FORMAT_B8G8R8_UINT;
case VK_FORMAT_B8G8R8_SINT: return GPU_FORMAT_B8G8R8_SINT;
case VK_FORMAT_B8G8R8_SRGB: return GPU_FORMAT_B8G8R8_SRGB;
case VK_FORMAT_R8G8B8A8_UINT: return GPU_FORMAT_R8G8B8A8_UINT;
case VK_FORMAT_R8G8B8A8_SINT: return GPU_FORMAT_R8G8B8A8_SINT;
case VK_FORMAT_R8G8B8A8_SRGB: return GPU_FORMAT_R8G8B8A8_SRGB;
case VK_FORMAT_B8G8R8A8_UINT: return GPU_FORMAT_B8G8R8A8_UINT;
case VK_FORMAT_B8G8R8A8_SINT: return GPU_FORMAT_B8G8R8A8_SINT;
case VK_FORMAT_B8G8R8A8_SRGB: return GPU_FORMAT_B8G8R8A8_SRGB;
case VK_FORMAT_R16_UINT: return GPU_FORMAT_R16_UINT;
case VK_FORMAT_R16_SINT: return GPU_FORMAT_R16_SINT;
case VK_FORMAT_R16_SFLOAT: return GPU_FORMAT_R16_SFLOAT;
case VK_FORMAT_R16G16_UINT: return GPU_FORMAT_R16G16_UINT;
case VK_FORMAT_R16G16_SINT: return GPU_FORMAT_R16G16_SINT;
case VK_FORMAT_R16G16_SFLOAT: return GPU_FORMAT_R16G16_SFLOAT;
case VK_FORMAT_R16G16B16_UINT: return GPU_FORMAT_R16G16B16_UINT;
case VK_FORMAT_R16G16B16_SINT: return GPU_FORMAT_R16G16B16_SINT;
case VK_FORMAT_R16G16B16_SFLOAT: return GPU_FORMAT_R16G16B16_SFLOAT;
case VK_FORMAT_R16G16B16A16_UINT: return GPU_FORMAT_R16G16B16A16_UINT;
case VK_FORMAT_R16G16B16A16_SINT: return GPU_FORMAT_R16G16B16A16_SINT;
case VK_FORMAT_R16G16B16A16_SFLOAT: return GPU_FORMAT_R16G16B16A16_SFLOAT;
case VK_FORMAT_R32_UINT: return GPU_FORMAT_R32_UINT;
case VK_FORMAT_R32_SINT: return GPU_FORMAT_R32_SINT;
case VK_FORMAT_R32_SFLOAT: return GPU_FORMAT_R32_SFLOAT;
case VK_FORMAT_R32G32_UINT: return GPU_FORMAT_R32G32_UINT;
case VK_FORMAT_R32G32_SINT: return GPU_FORMAT_R32G32_SINT;
case VK_FORMAT_R32G32_SFLOAT: return GPU_FORMAT_R32G32_SFLOAT;
case VK_FORMAT_R32G32B32_UINT: return GPU_FORMAT_R32G32B32_UINT;
case VK_FORMAT_R32G32B32_SINT: return GPU_FORMAT_R32G32B32_SINT;
case VK_FORMAT_R32G32B32_SFLOAT: return GPU_FORMAT_R32G32B32_SFLOAT;
case VK_FORMAT_R32G32B32A32_UINT: return GPU_FORMAT_R32G32B32A32_UINT;
case VK_FORMAT_R32G32B32A32_SINT: return GPU_FORMAT_R32G32B32A32_SINT;
case VK_FORMAT_R32G32B32A32_SFLOAT: return GPU_FORMAT_R32G32B32A32_SFLOAT;
case VK_FORMAT_R64_UINT: return GPU_FORMAT_R64_UINT;
case VK_FORMAT_R64_SINT: return GPU_FORMAT_R64_SINT;
case VK_FORMAT_R64_SFLOAT: return GPU_FORMAT_R64_SFLOAT;
case VK_FORMAT_R64G64_UINT: return GPU_FORMAT_R64G64_UINT;
case VK_FORMAT_R64G64_SINT: return GPU_FORMAT_R64G64_SINT;
case VK_FORMAT_R64G64_SFLOAT: return GPU_FORMAT_R64G64_SFLOAT;
case VK_FORMAT_R64G64B64_UINT: return GPU_FORMAT_R64G64B64_UINT;
case VK_FORMAT_R64G64B64_SINT: return GPU_FORMAT_R64G64B64_SINT;
case VK_FORMAT_R64G64B64_SFLOAT: return GPU_FORMAT_R64G64B64_SFLOAT;
case VK_FORMAT_R64G64B64A64_UINT: return GPU_FORMAT_R64G64B64A64_UINT;
case VK_FORMAT_R64G64B64A64_SINT: return GPU_FORMAT_R64G64B64A64_SINT;
case VK_FORMAT_R64G64B64A64_SFLOAT: return GPU_FORMAT_R64G64B64A64_SFLOAT;
case VK_FORMAT_D24_UNORM_S8_UINT: return GPU_FORMAT_D24_UNORM_S8_UINT;
case VK_FORMAT_D32_SFLOAT_S8_UINT: return GPU_FORMAT_D32_SFLOAT_S8_UINT;
default: return GPU_FORMAT_UNDEFINED;
}
}
wp_intern VkColorSpaceKHR vkColorspaceFromGpuColorspace(GpuColorspace colorspace) {
switch (colorspace) {
case GPU_COLOR_SPACE_SRGB_NONLINEAR: return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
case GPU_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: return VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT;
case GPU_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: return VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT;
case GPU_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: return VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT;
case GPU_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: return VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT;
case GPU_COLOR_SPACE_BT709_LINEAR_EXT: return VK_COLOR_SPACE_BT709_LINEAR_EXT;
case GPU_COLOR_SPACE_BT709_NONLINEAR_EXT: return VK_COLOR_SPACE_BT709_NONLINEAR_EXT;
case GPU_COLOR_SPACE_BT2020_LINEAR_EXT: return VK_COLOR_SPACE_BT2020_LINEAR_EXT;
case GPU_COLOR_SPACE_HDR10_ST2084_EXT: return VK_COLOR_SPACE_HDR10_ST2084_EXT;
case GPU_COLOR_SPACE_DOLBYVISION_EXT: return VK_COLOR_SPACE_DOLBYVISION_EXT;
case GPU_COLOR_SPACE_HDR10_HLG_EXT: return VK_COLOR_SPACE_HDR10_HLG_EXT;
case GPU_COLOR_SPACE_ADOBERGB_LINEAR_EXT: return VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT;
case GPU_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: return VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT;
case GPU_COLOR_SPACE_PASS_THROUGH_EXT: return VK_COLOR_SPACE_PASS_THROUGH_EXT;
case GPU_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: return VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT;
case GPU_COLORSPACE_SRGB_NONLINEAR: return VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
}
wp_intern GpuColorspace gpuColorspaceFromVkColorspace(VkColorSpaceKHR colorspace) {
switch (colorspace) {
case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: return GPU_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT;
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: return GPU_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT;
case VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: return GPU_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT;
case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: return GPU_COLOR_SPACE_DCI_P3_NONLINEAR_EXT;
case VK_COLOR_SPACE_BT709_LINEAR_EXT: return GPU_COLOR_SPACE_BT709_LINEAR_EXT;
case VK_COLOR_SPACE_BT709_NONLINEAR_EXT: return GPU_COLOR_SPACE_BT709_NONLINEAR_EXT;
case VK_COLOR_SPACE_BT2020_LINEAR_EXT: return GPU_COLOR_SPACE_BT2020_LINEAR_EXT;
case VK_COLOR_SPACE_HDR10_ST2084_EXT: return GPU_COLOR_SPACE_HDR10_ST2084_EXT;
case VK_COLOR_SPACE_DOLBYVISION_EXT: return GPU_COLOR_SPACE_DOLBYVISION_EXT;
case VK_COLOR_SPACE_HDR10_HLG_EXT: return GPU_COLOR_SPACE_HDR10_HLG_EXT;
case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT: return GPU_COLOR_SPACE_ADOBERGB_LINEAR_EXT;
case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: return GPU_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT;
case VK_COLOR_SPACE_PASS_THROUGH_EXT: return GPU_COLOR_SPACE_PASS_THROUGH_EXT;
case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: return GPU_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT;
case VK_COLORSPACE_SRGB_NONLINEAR_KHR: return GPU_COLORSPACE_SRGB_NONLINEAR;
default: return GPU_COLOR_SPACE_SRGB_NONLINEAR;
}
}
wp_intern VkPresentModeKHR vkPresentModeFromGpuPresentMode(GpuPresentMode mode) {
switch (mode) {
case GPU_PRESENT_MODE_IMMEDIATE: return VK_PRESENT_MODE_IMMEDIATE_KHR;
case GPU_PRESENT_MODE_FIFO: return VK_PRESENT_MODE_FIFO_KHR;
case GPU_PRESENT_MODE_FIFO_RELAXED: return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
case GPU_PRESENT_MODE_FIFO_LATEST_READY: return VK_PRESENT_MODE_FIFO_LATEST_READY_KHR;
}
}
wp_intern GpuPresentMode gpuPresentModeFromVkPresentMode(VkPresentModeKHR mode) {
switch (mode) {
case VK_PRESENT_MODE_FIFO_KHR: return GPU_PRESENT_MODE_FIFO;
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return GPU_PRESENT_MODE_FIFO_RELAXED;
case VK_PRESENT_MODE_FIFO_LATEST_READY_KHR: return GPU_PRESENT_MODE_FIFO_LATEST_READY;
default: return GPU_PRESENT_MODE_IMMEDIATE;
}
}
wp_intern VkImageType vkImageTypeFromGpuImageType(GpuImageType type) {
switch (type) {
case GPU_IMAGE_TYPE_1D: return VK_IMAGE_TYPE_1D;
case GPU_IMAGE_TYPE_2D: return VK_IMAGE_TYPE_2D;
case GPU_IMAGE_TYPE_3D: return VK_IMAGE_TYPE_3D;
}
}
wp_intern GpuImageType gpuImageTypeFromVkImageType(VkImageType type) {
switch (type) {
case VK_IMAGE_TYPE_1D: return GPU_IMAGE_TYPE_1D;
case VK_IMAGE_TYPE_2D: return GPU_IMAGE_TYPE_2D;
case VK_IMAGE_TYPE_3D: return GPU_IMAGE_TYPE_3D;
default: return GPU_IMAGE_TYPE_2D;
}
}
wp_intern VkImageViewType vkImageViewTypeFromGpuImageType(GpuImageType type) {
switch (type) {
case GPU_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
case GPU_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
case GPU_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
}
}
wp_intern GpuImageType gpuImageTypeFromVkImageViewType(VkImageViewType type) {
switch (type) {
case VK_IMAGE_VIEW_TYPE_1D: return GPU_IMAGE_TYPE_1D;
case VK_IMAGE_VIEW_TYPE_2D: return GPU_IMAGE_TYPE_2D;
case VK_IMAGE_VIEW_TYPE_3D: return GPU_IMAGE_TYPE_3D;
default: return GPU_IMAGE_TYPE_2D;
}
}
wp_intern VkSampleCountFlagBits vkSampleCountFromGpuSampleCount(GpuSampleCount samples) {
switch (samples) {
case GPU_SAMPLE_COUNT_1_BIT: return VK_SAMPLE_COUNT_1_BIT;
case GPU_SAMPLE_COUNT_2_BIT: return VK_SAMPLE_COUNT_2_BIT;
case GPU_SAMPLE_COUNT_4_BIT: return VK_SAMPLE_COUNT_4_BIT;
case GPU_SAMPLE_COUNT_8_BIT: return VK_SAMPLE_COUNT_8_BIT;
case GPU_SAMPLE_COUNT_16_BIT: return VK_SAMPLE_COUNT_16_BIT;
case GPU_SAMPLE_COUNT_32_BIT: return VK_SAMPLE_COUNT_32_BIT;
case GPU_SAMPLE_COUNT_64_BIT: return VK_SAMPLE_COUNT_64_BIT;
}
}
wp_intern GpuSampleCount gpuSampleCountFromVkSampleCount(VkSampleCountFlagBits samples) {
switch (samples) {
case VK_SAMPLE_COUNT_1_BIT: return GPU_SAMPLE_COUNT_1_BIT;
case VK_SAMPLE_COUNT_2_BIT: return GPU_SAMPLE_COUNT_2_BIT;
case VK_SAMPLE_COUNT_4_BIT: return GPU_SAMPLE_COUNT_4_BIT;
case VK_SAMPLE_COUNT_8_BIT: return GPU_SAMPLE_COUNT_8_BIT;
case VK_SAMPLE_COUNT_16_BIT: return GPU_SAMPLE_COUNT_16_BIT;
case VK_SAMPLE_COUNT_32_BIT: return GPU_SAMPLE_COUNT_32_BIT;
case VK_SAMPLE_COUNT_64_BIT: return GPU_SAMPLE_COUNT_64_BIT;
default: return GPU_SAMPLE_COUNT_1_BIT;
}
}
wp_intern VkImageTiling vkImageTilingFromGpuImageTiling(GpuImageTiling tiling) {
switch (tiling) {
case GPU_IMAGE_TILING_LINEAR: return VK_IMAGE_TILING_LINEAR;
default: return VK_IMAGE_TILING_OPTIMAL;
}
}
wp_intern GpuImageTiling gpuImageTilingFromVkImageTiling(VkImageTiling tiling) {
switch (tiling) {
case VK_IMAGE_TILING_LINEAR: return GPU_IMAGE_TILING_LINEAR;
default: return GPU_IMAGE_TILING_OPTIMAL;
}
}
wp_intern VkImageUsageFlags vkImageUsageFromGpuImageUsage(GpuImageUsage usage) {
VkImageUsageFlags output = 0;
output |= (usage & GPU_IMAGE_USAGE_TRANSFER_SRC) != 0 ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_TRANSFER_DST) != 0 ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_SAMPLED) != 0 ? VK_IMAGE_USAGE_SAMPLED_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_STORAGE) != 0 ? VK_IMAGE_USAGE_STORAGE_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_COLOR_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_TRANSIENT_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_INPUT_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_HOST_TRANSFER) != 0 ? VK_IMAGE_USAGE_HOST_TRANSFER_BIT : 0;
output |= (usage & GPU_IMAGE_USAGE_VIDEO_DECODE_DST) != 0 ? VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR : 0;
output |= (usage & GPU_IMAGE_USAGE_VIDEO_DECODE_SRC) != 0 ? VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR : 0;
output |= (usage & GPU_IMAGE_USAGE_FRAGMENT_DENSITY_MAP) != 0 ? VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT : 0;
output |= (usage & GPU_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR : 0;
output |= (usage & GPU_IMAGE_USAGE_VIDEO_ENCODE_DST) != 0 ? VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR : 0;
output |= (usage & GPU_IMAGE_USAGE_VIDEO_ENCODE_SRC) != 0 ? VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR : 0;
return output;
}
wp_intern GpuImageUsage gpuImageUsageFromVkImageUsage(VkImageUsageFlags usage) {
GpuImageUsage output = 0;
output |= (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSFER_SRC : 0;
output |= (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSFER_DST : 0;
output |= (usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0 ? GPU_IMAGE_USAGE_SAMPLED : 0;
output |= (usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0 ? GPU_IMAGE_USAGE_STORAGE : 0;
output |= (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_COLOR_ATTACHMENT : 0;
output |= (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT : 0;
output |= (usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSIENT_ATTACHMENT : 0;
output |= (usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_INPUT_ATTACHMENT : 0;
output |= (usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT) != 0 ? GPU_IMAGE_USAGE_HOST_TRANSFER : 0;
output |= (usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_DECODE_DST : 0;
output |= (usage & VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_DECODE_SRC : 0;
output |= (usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) != 0 ? GPU_IMAGE_USAGE_FRAGMENT_DENSITY_MAP : 0;
output |= (usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT : 0;
output |= (usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_ENCODE_DST : 0;
output |= (usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_ENCODE_SRC : 0;
return output;
}
wp_intern VkImageLayout vkImageLayoutFromGpuImageLayout(GpuImageLayout layout) {
switch (layout) {
case GPU_IMAGE_LAYOUT_GENERAL: return VK_IMAGE_LAYOUT_GENERAL;
case GPU_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL;
case GPU_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
case GPU_IMAGE_LAYOUT_PRESENT_SRC: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case GPU_IMAGE_LAYOUT_VIDEO_DECODE_DST: return VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR;
case GPU_IMAGE_LAYOUT_VIDEO_DECODE_SRC: return VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR;
case GPU_IMAGE_LAYOUT_SHARED_PRESENT: return VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
case GPU_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL: return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
case GPU_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_DST: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR;
case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_SRC: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR;
case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR;
default: return VK_IMAGE_LAYOUT_UNDEFINED;
}
}
wp_intern GpuImageLayout gpuImageLayoutFromVkImageLayout(VkImageLayout layout) {
switch (layout) {
case VK_IMAGE_LAYOUT_GENERAL: return GPU_IMAGE_LAYOUT_GENERAL;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return GPU_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: return GPU_IMAGE_LAYOUT_PRESENT_SRC;
case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR: return GPU_IMAGE_LAYOUT_VIDEO_DECODE_DST;
case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR: return GPU_IMAGE_LAYOUT_VIDEO_DECODE_SRC;
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: return GPU_IMAGE_LAYOUT_SHARED_PRESENT;
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: return GPU_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL;
case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR: return GPU_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_DST;
case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_SRC;
case VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP;
default: return GPU_IMAGE_LAYOUT_UNDEFINED;
}
}
wp_intern VkImageAspectFlags vkImageAspectFromGpuImageAspect(GpuImageAspect aspect) {
VkImageAspectFlags output = VK_IMAGE_ASPECT_NONE;
output |= (aspect & GPU_IMAGE_ASPECT_COLOR_BIT) != 0 ? VK_IMAGE_ASPECT_COLOR_BIT : 0;
output |= (aspect & GPU_IMAGE_ASPECT_DEPTH_BIT) != 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0;
output |= (aspect & GPU_IMAGE_ASPECT_STENCIL_BIT) != 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0;
return output;
}
wp_intern GpuImageAspect gpuImageAspectFromVkImageAspect(VkImageAspectFlags aspect) {
GpuImageAspect output = GPU_IMAGE_ASPECT_NONE;
output |= (aspect & VK_IMAGE_ASPECT_COLOR_BIT) != 0 ? GPU_IMAGE_ASPECT_COLOR_BIT : 0;
output |= (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 ? GPU_IMAGE_ASPECT_DEPTH_BIT : 0;
output |= (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 ? GPU_IMAGE_ASPECT_STENCIL_BIT : 0;
return output;
}
wp_intern VkBufferUsageFlags2 vkBufferUsageFromGpuBufferUsage(GpuBufferUsage usage) {
VkBufferUsageFlags2 output = 0;
output |= (usage & GPU_BUFFER_USAGE_TRANSFER_SRC) != 0 ? VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_TRANSFER_DST) != 0 ? VK_BUFFER_USAGE_2_TRANSFER_DST_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER) != 0 ? VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_STORAGE_TEXEL_BUFFER) != 0 ? VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_UNIFORM_BUFFER) != 0 ? VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_STORAGE_BUFFER) != 0 ? VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_INDEX_BUFFER) != 0 ? VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_VERTEX_BUFFER) != 0 ? VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_INDIRECT_BUFFER) != 0 ? VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) != 0 ? VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT : 0;
output |= (usage & GPU_BUFFER_USAGE_DESCRIPTOR_HEAP) != 0 ? VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_CONDITIONAL_RENDERING) != 0 ? VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_SHADER_BINDING_TABLE) != 0 ? VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR : 0;
output |= (usage & GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER) != 0 ? VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER) != 0 ? VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_VIDEO_DECODE_SRC) != 0 ? VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR : 0;
output |= (usage & GPU_BUFFER_USAGE_VIDEO_DECODE_DST) != 0 ? VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR : 0;
output |= (usage & GPU_BUFFER_USAGE_VIDEO_ENCODE_DST) != 0 ? VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR : 0;
output |= (usage & GPU_BUFFER_USAGE_VIDEO_ENCODE_SRC) != 0 ? VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR : 0;
output |= (usage & GPU_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT : 0;
output |= (usage & GPU_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT : 0;
return output;
}
wp_intern GpuBufferUsage gpuBufferUsageFromVkBufferUsage(VkBufferUsageFlags2 usage) {
GpuBufferUsage output = 0;
output |= (usage & VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT) != 0 ? GPU_BUFFER_USAGE_TRANSFER_SRC : 0;
output |= (usage & VK_BUFFER_USAGE_2_TRANSFER_DST_BIT) != 0 ? GPU_BUFFER_USAGE_TRANSFER_DST : 0;
output |= (usage & VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_STORAGE_TEXEL_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_UNIFORM_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_STORAGE_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_INDEX_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_VERTEX_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_INDIRECT_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT) != 0 ? GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS : 0;
output |= (usage & VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_DESCRIPTOR_HEAP : 0;
output |= (usage & VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_CONDITIONAL_RENDERING : 0;
output |= (usage & VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_SHADER_BINDING_TABLE : 0;
output |= (usage & VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_DECODE_SRC : 0;
output |= (usage & VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_DECODE_DST : 0;
output |= (usage & VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_ENCODE_DST : 0;
output |= (usage & VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_ENCODE_SRC : 0;
output |= (usage & VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER : 0;
output |= (usage & VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER : 0;
return output;
}
wp_intern VkPipelineStageFlags2 vkPipelineStagesFromGpuPipelineStages(GpuPipelineStageFlags stage) {
VkPipelineStageFlags2 output = 0;
output |= (stage & GPU_PIPELINE_STAGE_TOP_OF_PIPE) != 0 ? VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_DRAW_INDIRECT) != 0 ? VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_VERTEX_INPUT) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_VERTEX_SHADER) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_GEOMETRY_SHADER) != 0 ? VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_SHADER) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS) != 0 ? VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_LATE_FRAGMENT_TESTS) != 0 ? VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT) != 0 ? VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_COMPUTE_SHADER) != 0 ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_ALL_TRANSFER) != 0 ? VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_TRANSFER) != 0 ? VK_PIPELINE_STAGE_2_TRANSFER_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_BOTTOM_OF_PIPE) != 0 ? VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_HOST) != 0 ? VK_PIPELINE_STAGE_2_HOST_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_ALL_GRAPHICS) != 0 ? VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_ALL_COMMANDS) != 0 ? VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_COPY) != 0 ? VK_PIPELINE_STAGE_2_COPY_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_RESOLVE) != 0 ? VK_PIPELINE_STAGE_2_RESOLVE_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_BLIT) != 0 ? VK_PIPELINE_STAGE_2_BLIT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_CLEAR) != 0 ? VK_PIPELINE_STAGE_2_CLEAR_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_INDEX_INPUT) != 0 ? VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_VERTEX_ATTRIBUTE_INPUT) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_PRE_RASTERIZATION_SHADERS) != 0 ? VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT : 0;
output |= (stage & GPU_PIPELINE_STAGE_VIDEO_DECODE) != 0 ? VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_VIDEO_ENCODE) != 0 ? VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_CONDITIONAL_RENDERING) != 0 ? VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_COMMAND_PREPROCESS) != 0 ? VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD) != 0 ? VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_RAY_TRACING_SHADER) != 0 ? VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_TASK_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_MESH_SHADER) != 0 ? VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_COPY) != 0 ? VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_MICROMAP_BUILD) != 0 ? VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT : 0;
output |= (stage & GPU_PIPELINE_STAGE_COPY_INDIRECT) != 0 ? VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR : 0;
output |= (stage & GPU_PIPELINE_STAGE_MEMORY_DECOMPRESSION) != 0 ? VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT : 0;
return output;
}
wp_intern GpuPipelineStageFlags gpuPipelineStagesFromVkPipelineStages(VkPipelineStageFlags2 stage) {
GpuPipelineStageFlags output = 0;
output |= (stage & VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT) != 0 ? GPU_PIPELINE_STAGE_TOP_OF_PIPE : 0;
output |= (stage & VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT) != 0 ? GPU_PIPELINE_STAGE_DRAW_INDIRECT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_INPUT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_GEOMETRY_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT) != 0 ? GPU_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT) != 0 ? GPU_PIPELINE_STAGE_LATE_FRAGMENT_TESTS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_COMPUTE_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ALL_TRANSFER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_TRANSFER_BIT) != 0 ? GPU_PIPELINE_STAGE_TRANSFER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) != 0 ? GPU_PIPELINE_STAGE_BOTTOM_OF_PIPE : 0;
output |= (stage & VK_PIPELINE_STAGE_2_HOST_BIT) != 0 ? GPU_PIPELINE_STAGE_HOST : 0;
output |= (stage & VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT) != 0 ? GPU_PIPELINE_STAGE_ALL_GRAPHICS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT) != 0 ? GPU_PIPELINE_STAGE_ALL_COMMANDS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_COPY_BIT) != 0 ? GPU_PIPELINE_STAGE_COPY : 0;
output |= (stage & VK_PIPELINE_STAGE_2_RESOLVE_BIT) != 0 ? GPU_PIPELINE_STAGE_RESOLVE : 0;
output |= (stage & VK_PIPELINE_STAGE_2_BLIT_BIT) != 0 ? GPU_PIPELINE_STAGE_BLIT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_CLEAR_BIT) != 0 ? GPU_PIPELINE_STAGE_CLEAR : 0;
output |= (stage & VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_INDEX_INPUT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_ATTRIBUTE_INPUT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT) != 0 ? GPU_PIPELINE_STAGE_PRE_RASTERIZATION_SHADERS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_VIDEO_DECODE : 0;
output |= (stage & VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_VIDEO_ENCODE : 0;
output |= (stage & VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_CONDITIONAL_RENDERING : 0;
output |= (stage & VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_COMMAND_PREPROCESS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD : 0;
output |= (stage & VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_RAY_TRACING_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS : 0;
output |= (stage & VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_TASK_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MESH_SHADER : 0;
output |= (stage & VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_COPY : 0;
output |= (stage & VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MICROMAP_BUILD : 0;
output |= (stage & VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_COPY_INDIRECT : 0;
output |= (stage & VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MEMORY_DECOMPRESSION : 0;
return output;
}
wp_intern VkAccessFlags2 vkAccessFlagsFromGpuAccessFlags(GpuAccessFlags access) {
VkAccessFlags2 output = 0;
output |= (access & GPU_ACCESS_NONE) != 0 ? VK_ACCESS_2_NONE : 0;
output |= (access & GPU_ACCESS_INDIRECT_COMMAND_READ) != 0 ? VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT : 0;
output |= (access & GPU_ACCESS_INDEX_READ) != 0 ? VK_ACCESS_2_INDEX_READ_BIT : 0;
output |= (access & GPU_ACCESS_VERTEX_ATTRIBUTE_READ) != 0 ? VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT : 0;
output |= (access & GPU_ACCESS_UNIFORM_READ) != 0 ? VK_ACCESS_2_UNIFORM_READ_BIT : 0;
output |= (access & GPU_ACCESS_INPUT_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT : 0;
output |= (access & GPU_ACCESS_SHADER_READ) != 0 ? VK_ACCESS_2_SHADER_READ_BIT : 0;
output |= (access & GPU_ACCESS_SHADER_WRITE) != 0 ? VK_ACCESS_2_SHADER_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT : 0;
output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_WRITE) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT : 0;
output |= (access & GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE) != 0 ? VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_TRANSFER_READ) != 0 ? VK_ACCESS_2_TRANSFER_READ_BIT : 0;
output |= (access & GPU_ACCESS_TRANSFER_WRITE) != 0 ? VK_ACCESS_2_TRANSFER_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_HOST_READ) != 0 ? VK_ACCESS_2_HOST_READ_BIT : 0;
output |= (access & GPU_ACCESS_HOST_WRITE) != 0 ? VK_ACCESS_2_HOST_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_MEMORY_READ) != 0 ? VK_ACCESS_2_MEMORY_READ_BIT : 0;
output |= (access & GPU_ACCESS_MEMORY_WRITE) != 0 ? VK_ACCESS_2_MEMORY_WRITE_BIT : 0;
output |= (access & GPU_ACCESS_SHADER_SAMPLED_READ) != 0 ? VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_SHADER_STORAGE_READ) != 0 ? VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_SHADER_STORAGE_WRITE) != 0 ? VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR : 0;
output |= (access & GPU_ACCESS_VIDEO_DECODE_READ) != 0 ? VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_VIDEO_DECODE_WRITE) != 0 ? VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR : 0;
output |= (access & GPU_ACCESS_SAMPLER_HEAP_READ) != 0 ? VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_RESOURCE_HEAP_READ) != 0 ? VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_VIDEO_ENCODE_READ) != 0 ? VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_VIDEO_ENCODE_WRITE) != 0 ? VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR : 0;
output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_WRITE) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT : 0;
output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT : 0;
output |= (access & GPU_ACCESS_CONDITIONAL_RENDERING_READ) != 0 ? VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_COMMAND_PREPROCESS_READ) != 0 ? VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_COMMAND_PREPROCESS_WRITE) != 0 ? VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_EXT : 0;
output |= (access & GPU_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_ACCELERATION_STRUCTURE_READ) != 0 ? VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_ACCELERATION_STRUCTURE_WRITE) != 0 ? VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR : 0;
output |= (access & GPU_ACCESS_FRAGMENT_DENSITY_MAP_READ) != 0 ? VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT : 0;
output |= (access & GPU_ACCESS_DESCRIPTOR_BUFFER_READ) != 0 ? VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_SHADER_BINDING_TABLE_READ) != 0 ? VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR : 0;
output |= (access & GPU_ACCESS_MICROMAP_READ) != 0 ? VK_ACCESS_2_MICROMAP_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_MICROMAP_WRITE) != 0 ? VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT : 0;
output |= (access & GPU_ACCESS_MEMORY_DECOMPRESSION_READ) != 0 ? VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT : 0;
output |= (access & GPU_ACCESS_MEMORY_DECOMPRESSION_WRITE) != 0 ? VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT : 0;
return output;
}
wp_intern GpuAccessFlags gpuAccessFlagsFromVkAccessFlags(VkAccessFlags2 access) {
GpuAccessFlags output = 0;
output |= (access & VK_ACCESS_2_NONE) != 0 ? GPU_ACCESS_NONE : 0;
output |= (access & VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT) != 0 ? GPU_ACCESS_INDIRECT_COMMAND_READ : 0;
output |= (access & VK_ACCESS_2_INDEX_READ_BIT) != 0 ? GPU_ACCESS_INDEX_READ : 0;
output |= (access & VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT) != 0 ? GPU_ACCESS_VERTEX_ATTRIBUTE_READ : 0;
output |= (access & VK_ACCESS_2_UNIFORM_READ_BIT) != 0 ? GPU_ACCESS_UNIFORM_READ : 0;
output |= (access & VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_INPUT_ATTACHMENT_READ : 0;
output |= (access & VK_ACCESS_2_SHADER_READ_BIT) != 0 ? GPU_ACCESS_SHADER_READ : 0;
output |= (access & VK_ACCESS_2_SHADER_WRITE_BIT) != 0 ? GPU_ACCESS_SHADER_WRITE : 0;
output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_READ : 0;
output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_WRITE : 0;
output |= (access & VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ : 0;
output |= (access & VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) != 0 ? GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE : 0;
output |= (access & VK_ACCESS_2_TRANSFER_READ_BIT) != 0 ? GPU_ACCESS_TRANSFER_READ : 0;
output |= (access & VK_ACCESS_2_TRANSFER_WRITE_BIT) != 0 ? GPU_ACCESS_TRANSFER_WRITE : 0;
output |= (access & VK_ACCESS_2_HOST_READ_BIT) != 0 ? GPU_ACCESS_HOST_READ : 0;
output |= (access & VK_ACCESS_2_HOST_WRITE_BIT) != 0 ? GPU_ACCESS_HOST_WRITE : 0;
output |= (access & VK_ACCESS_2_MEMORY_READ_BIT) != 0 ? GPU_ACCESS_MEMORY_READ : 0;
output |= (access & VK_ACCESS_2_MEMORY_WRITE_BIT) != 0 ? GPU_ACCESS_MEMORY_WRITE : 0;
output |= (access & VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_SAMPLED_READ : 0;
output |= (access & VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_STORAGE_READ : 0;
output |= (access & VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_STORAGE_WRITE : 0;
output |= (access & VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_DECODE_READ : 0;
output |= (access & VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_DECODE_WRITE : 0;
output |= (access & VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_SAMPLER_HEAP_READ : 0;
output |= (access & VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_RESOURCE_HEAP_READ : 0;
output |= (access & VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_ENCODE_READ : 0;
output |= (access & VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_ENCODE_WRITE : 0;
output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_WRITE : 0;
output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ : 0;
output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE : 0;
output |= (access & VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT) != 0 ? GPU_ACCESS_CONDITIONAL_RENDERING_READ : 0;
output |= (access & VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_EXT) != 0 ? GPU_ACCESS_COMMAND_PREPROCESS_READ : 0;
output |= (access & VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_COMMAND_PREPROCESS_WRITE : 0;
output |= (access & VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR) != 0 ? GPU_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ : 0;
output |= (access & VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR) != 0 ? GPU_ACCESS_ACCELERATION_STRUCTURE_READ : 0;
output |= (access & VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_ACCELERATION_STRUCTURE_WRITE : 0;
output |= (access & VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_FRAGMENT_DENSITY_MAP_READ : 0;
output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT : 0;
output |= (access & VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT) != 0 ? GPU_ACCESS_DESCRIPTOR_BUFFER_READ : 0;
output |= (access & VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_BINDING_TABLE_READ : 0;
output |= (access & VK_ACCESS_2_MICROMAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_MICROMAP_READ : 0;
output |= (access & VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_MICROMAP_WRITE : 0;
output |= (access & VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT) != 0 ? GPU_ACCESS_MEMORY_DECOMPRESSION_READ : 0;
output |= (access & VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_MEMORY_DECOMPRESSION_WRITE : 0;
return output;
}
wp_intern VkFilter vkFilterFromGpuFilter(GpuFilter filter) {
switch (filter) {
case GPU_FILTER_NEAREST: return VK_FILTER_NEAREST;
case GPU_FILTER_LINEAR: return VK_FILTER_LINEAR;
case GPU_FILTER_CUBIC: return VK_FILTER_CUBIC_EXT;
}
}
wp_intern GpuFilter gpuFilterFromVkFilter(VkFilter filter) {
switch (filter) {
case VK_FILTER_NEAREST: return GPU_FILTER_NEAREST;
case VK_FILTER_LINEAR: return GPU_FILTER_LINEAR;
case VK_FILTER_CUBIC_EXT: return GPU_FILTER_CUBIC;
default: return GPU_FILTER_LINEAR;
}
}
wp_intern VkSamplerMipmapMode vkSamplerMipmapModeFromGpuSamplerMipmapMode(GpuSamplerMipmapMode mode) {
switch (mode) {
case GPU_SAMPLER_MIPMAP_MODE_NEAREST: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case GPU_SAMPLER_MIPMAP_MODE_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
}
}
wp_intern GpuSamplerMipmapMode gpuSamplerMipmapModeFromVkSamplerMipmapMode(VkSamplerMipmapMode mode) {
switch (mode) {
case VK_SAMPLER_MIPMAP_MODE_NEAREST: return GPU_SAMPLER_MIPMAP_MODE_NEAREST;
case VK_SAMPLER_MIPMAP_MODE_LINEAR: return GPU_SAMPLER_MIPMAP_MODE_LINEAR;
default: return GPU_SAMPLER_MIPMAP_MODE_LINEAR;
}
}
wp_intern VkSamplerAddressMode vkSamplerAddressModeFromGpuSamplerAddressMode(GpuSamplerAddressMode mode) {
switch (mode) {
case GPU_SAMPLER_ADDRESS_MODE_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case GPU_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case GPU_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
}
}
wp_intern GpuSamplerAddressMode gpuSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode mode) {
switch (mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT: return GPU_SAMPLER_ADDRESS_MODE_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return GPU_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return GPU_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
}
}
wp_intern VkCompareOp vkCompareOpFromGpuCompareOp(GpuCompareOp op) {
switch (op) {
case GPU_COMPARE_OP_NEVER: return VK_COMPARE_OP_NEVER;
case GPU_COMPARE_OP_LESS: return VK_COMPARE_OP_LESS;
case GPU_COMPARE_OP_EQUAL: return VK_COMPARE_OP_EQUAL;
case GPU_COMPARE_OP_LESS_OR_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
case GPU_COMPARE_OP_GREATER: return VK_COMPARE_OP_GREATER;
case GPU_COMPARE_OP_NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL;
case GPU_COMPARE_OP_GREATER_OR_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
case GPU_COMPARE_OP_ALWAYS: return VK_COMPARE_OP_ALWAYS;
}
}
wp_intern GpuCompareOp gpuCompareOpFromVkCompareOp(VkCompareOp op) {
switch (op) {
case VK_COMPARE_OP_NEVER: return GPU_COMPARE_OP_NEVER;
case VK_COMPARE_OP_LESS: return GPU_COMPARE_OP_LESS;
case VK_COMPARE_OP_EQUAL: return GPU_COMPARE_OP_EQUAL;
case VK_COMPARE_OP_LESS_OR_EQUAL: return GPU_COMPARE_OP_LESS_OR_EQUAL;
case VK_COMPARE_OP_GREATER: return GPU_COMPARE_OP_GREATER;
case VK_COMPARE_OP_NOT_EQUAL: return GPU_COMPARE_OP_NOT_EQUAL;
case VK_COMPARE_OP_GREATER_OR_EQUAL: return GPU_COMPARE_OP_GREATER_OR_EQUAL;
case VK_COMPARE_OP_ALWAYS: return GPU_COMPARE_OP_ALWAYS;
default: return GPU_COMPARE_OP_NEVER;
}
}
wp_intern VkDescriptorType vkDescriptorTypeFromGpuDescriptorType(GpuDescriptorType type) {
switch (type) {
case GPU_DESCRIPTOR_TYPE_SAMPLER: return VK_DESCRIPTOR_TYPE_SAMPLER;
case GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
case GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
case GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
case GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
case GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
default: break;
}
assertWithLogger(false, &logger, "Invalid GPU descriptor type");
}
wp_intern GpuDescriptorType gpuDescriptorTypeFromVkDescriptorType(VkDescriptorType type) {
switch (type) {
case VK_DESCRIPTOR_TYPE_SAMPLER: return GPU_DESCRIPTOR_TYPE_SAMPLER;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
default: break;
}
assertWithLogger(false, &logger, "Invalid Vulkan descriptor type");
}
wp_intern VkShaderStageFlags vkShaderStageFromGpuShaderStage(GpuShaderStage stages) {
VkShaderStageFlags output = 0;
output |= (stages & GPU_SHADER_STAGE_VERTEX) != 0 ? VK_SHADER_STAGE_VERTEX_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_TESSELLATION_CONTROL) != 0 ? VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_TESSELLATION_EVALUATION) != 0 ? VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_GEOMETRY) != 0 ? VK_SHADER_STAGE_GEOMETRY_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_FRAGMENT) != 0 ? VK_SHADER_STAGE_FRAGMENT_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_COMPUTE) != 0 ? VK_SHADER_STAGE_COMPUTE_BIT : 0;
output |= (stages & GPU_SHADER_STAGE_ALL_GRAPHICS) != 0 ? VK_SHADER_STAGE_ALL_GRAPHICS : 0;
output |= (stages & GPU_SHADER_STAGE_ALL) != 0 ? VK_SHADER_STAGE_ALL : 0;
output |= (stages & GPU_SHADER_STAGE_RAYGEN) != 0 ? VK_SHADER_STAGE_RAYGEN_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_ANY_HIT) != 0 ? VK_SHADER_STAGE_ANY_HIT_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_CLOSEST_HIT) != 0 ? VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_MISS) != 0 ? VK_SHADER_STAGE_MISS_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_INTERSECTION) != 0 ? VK_SHADER_STAGE_INTERSECTION_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_CALLABLE) != 0 ? VK_SHADER_STAGE_CALLABLE_BIT_KHR : 0;
output |= (stages & GPU_SHADER_STAGE_TASK) != 0 ? VK_SHADER_STAGE_TASK_BIT_EXT : 0;
output |= (stages & GPU_SHADER_STAGE_MESH) != 0 ? VK_SHADER_STAGE_MESH_BIT_EXT : 0;
return output;
}
wp_intern GpuShaderStage gpuShaderStageFromVkShaderStage(VkShaderStageFlags stages) {
GpuShaderStage output = 0;
output |= (stages & VK_SHADER_STAGE_VERTEX_BIT) != 0 ? GPU_SHADER_STAGE_VERTEX : 0;
output |= (stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0 ? GPU_SHADER_STAGE_TESSELLATION_CONTROL : 0;
output |= (stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0 ? GPU_SHADER_STAGE_TESSELLATION_EVALUATION : 0;
output |= (stages & VK_SHADER_STAGE_GEOMETRY_BIT) != 0 ? GPU_SHADER_STAGE_GEOMETRY : 0;
output |= (stages & VK_SHADER_STAGE_FRAGMENT_BIT) != 0 ? GPU_SHADER_STAGE_FRAGMENT : 0;
output |= (stages & VK_SHADER_STAGE_COMPUTE_BIT) != 0 ? GPU_SHADER_STAGE_COMPUTE : 0;
output |= (stages & VK_SHADER_STAGE_ALL_GRAPHICS) != 0 ? GPU_SHADER_STAGE_ALL_GRAPHICS : 0;
output |= (stages & VK_SHADER_STAGE_ALL) != 0 ? GPU_SHADER_STAGE_ALL : 0;
output |= (stages & VK_SHADER_STAGE_RAYGEN_BIT_KHR) != 0 ? GPU_SHADER_STAGE_RAYGEN : 0;
output |= (stages & VK_SHADER_STAGE_ANY_HIT_BIT_KHR) != 0 ? GPU_SHADER_STAGE_ANY_HIT : 0;
output |= (stages & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR) != 0 ? GPU_SHADER_STAGE_CLOSEST_HIT : 0;
output |= (stages & VK_SHADER_STAGE_MISS_BIT_KHR) != 0 ? GPU_SHADER_STAGE_MISS : 0;
output |= (stages & VK_SHADER_STAGE_INTERSECTION_BIT_KHR) != 0 ? GPU_SHADER_STAGE_INTERSECTION : 0;
output |= (stages & VK_SHADER_STAGE_CALLABLE_BIT_KHR) != 0 ? GPU_SHADER_STAGE_CALLABLE : 0;
output |= (stages & VK_SHADER_STAGE_TASK_BIT_EXT) != 0 ? GPU_SHADER_STAGE_TASK : 0;
output |= (stages & VK_SHADER_STAGE_MESH_BIT_EXT) != 0 ? GPU_SHADER_STAGE_MESH : 0;
return output;
}
wp_intern GpuDescriptorCategory descriptorCategoryFromDescriptorType(GpuDescriptorType type) {
switch (type) {
case GPU_DESCRIPTOR_TYPE_SAMPLER:
case GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
return GPU_DESCRIPTOR_CATEGORY_IMAGE;
case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
return GPU_DESCRIPTOR_CATEGORY_BUFFER;
case GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
return GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER;
case GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
return GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK;
default:
break;
}
assertWithLogger(0, &logger, "Unrecognised descriptor type");
}
wp_intern u64 retrieveDescriptorImageInfos(const GpuDescriptorSetWriteInfo *src_write_info,
VkWriteDescriptorSet *dst_write_info,
VkDescriptorImageInfoArray dst_img_infos,
u64 dst_img_infos_offset) {
u64 img_desc_count = wpArrayCount(src_write_info->image_infos);
for (u64 j = 0; j < img_desc_count; ++j) {
GpuDescriptorImageInfo *img_info = &(src_write_info->image_infos[j]);
VkDescriptorImageInfo vk_img_info = {
.sampler = img_info->sampler != NULL ? img_info->sampler->vk_sampler : NULL,
.imageView = img_info->image != NULL ? img_info->image->vk_view : NULL,
.imageLayout = vkImageLayoutFromGpuImageLayout(img_info->image_layout),
};
wpArrayAppendCapped(VkDescriptorImageInfo, dst_img_infos, &vk_img_info);
}
dst_write_info->descriptorCount = img_desc_count;
dst_write_info->pImageInfo = &dst_img_infos[dst_img_infos_offset];
return img_desc_count;
}
wp_intern u64 retrieveDescriptorBufferInfos(const GpuDescriptorSetWriteInfo *src_write_info,
VkWriteDescriptorSet *dst_write_info,
VkDescriptorBufferInfoArray dst_buf_infos,
u64 dst_buf_infos_offset) {
u64 buf_desc_count = wpArrayCount(src_write_info->buffer_infos);
for (u64 j = 0; j < buf_desc_count; ++j) {
GpuDescriptorBufferInfo *buf_info = &(src_write_info->buffer_infos[j]);
VkDescriptorBufferInfo vk_buf_info = {
.buffer = buf_info->buffer->internal->vk_buffer,
.offset = buf_info->offset,
.range = buf_info->range > 0 ? buf_info->range : VK_WHOLE_SIZE,
};
wpArrayAppendCapped(VkDescriptorBufferInfo, dst_buf_infos, &vk_buf_info);
}
dst_write_info->descriptorCount = buf_desc_count;
dst_write_info->pBufferInfo = &dst_buf_infos[dst_buf_infos_offset];
return buf_desc_count;
}
wp_intern GraphicsPipelinesTotalCounts queryGraphicsPipelinesRequestTotalCounts(GpuGraphicsPipelinesCreateRequest request) {
GraphicsPipelinesTotalCounts output = {0};
for (u64 i = 0; i < wpArrayCount(request.infos); ++i) {
GpuGraphicsPipelineCreateInfo *info = &request.infos[i];
output.total_vertex_input_bindings_count += wpArrayCount(info->vertex_input_state.bindings);
output.total_vertex_input_attributes_count += wpArrayCount(info->vertex_input_state.attributes);
output.total_color_blend_attachments_count += wpArrayCount(info->color_blend_state.attachments);
output.total_shader_stages_count += wpArrayCount(info->shader_stages);
}
return output;
}
wp_intern GraphicsPipelinesTempArrays allocateGraphicsPipelinesTempArrays(const WpAllocator *allocator,
GpuGraphicsPipelinesCreateRequest request) {
u64 pipeline_count = wpArrayCount(request.infos);
GraphicsPipelinesTotalCounts counts = queryGraphicsPipelinesRequestTotalCounts(request);
GraphicsPipelinesTempArrays output = {
.vertex_input_states = wpArrayAllocCapacity(VkPipelineVertexInputStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.input_assembly_states = wpArrayAllocCapacity(VkPipelineInputAssemblyStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.tesselation_states = wpArrayAllocCapacity(VkPipelineTessellationStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.viewport_states = wpArrayAllocCapacity(VkPipelineViewportStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.rasterization_states = wpArrayAllocCapacity(VkPipelineRasterizationStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.multisample_states = wpArrayAllocCapacity(VkPipelineMultisampleStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.depth_stencil_states = wpArrayAllocCapacity(VkPipelineDepthStencilStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.color_blend_states = wpArrayAllocCapacity(VkPipelineColorBlendStateCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.dynamic_rendering_infos = wpArrayAllocCapacity(VkPipelineRenderingCreateInfo, allocator,
pipeline_count, WP_ARRAY_INIT_FILLED),
.color_attachment_formats = wpArrayAllocCapacity(VkFormat, allocator, pipeline_count,
WP_ARRAY_INIT_FILLED),
.vertex_bindings = wpArrayAllocCapacity(VkVertexInputBindingDescription, allocator,
counts.total_vertex_input_bindings_count,
WP_ARRAY_INIT_FILLED),
.vertex_attributes = wpArrayAllocCapacity(VkVertexInputAttributeDescription, allocator,
counts.total_vertex_input_attributes_count,
WP_ARRAY_INIT_FILLED),
.color_blend_attachments = wpArrayAllocCapacity(VkPipelineColorBlendAttachmentState, allocator,
counts.total_color_blend_attachments_count,
WP_ARRAY_INIT_FILLED),
.shader_stages = wpArrayAllocCapacity(VkPipelineShaderStageCreateInfo, allocator,
counts.total_shader_stages_count, WP_ARRAY_INIT_FILLED),
};
b8 allocations_successful = output.vertex_input_states != NULL && output.input_assembly_states != NULL &&
output.tesselation_states != NULL && output.viewport_states != NULL &&
output.rasterization_states != NULL && output.multisample_states != NULL &&
output.depth_stencil_states != NULL && output.color_blend_states != NULL &&
output.dynamic_rendering_infos && output.color_attachment_formats != NULL &&
output.vertex_bindings != NULL && output.vertex_attributes != NULL &&
output.color_blend_attachments != NULL && output.shader_stages != NULL;
assertWithLogger(allocations_successful, &logger, "Failed to allocate graphics pipelines temporary arrays");
return output;
}
wp_intern VkVertexInputRate vkVertexInputRateFromGpuVertexInputRate(GpuVertexInputRate rate) {
switch (rate) {
case GPU_VERTEX_INPUT_RATE_VERTEX: return VK_VERTEX_INPUT_RATE_VERTEX;
case GPU_VERTEX_INPUT_RATE_INSTANCE: return VK_VERTEX_INPUT_RATE_INSTANCE;
}
}
wp_intern GpuVertexInputRate gpuVertexInputRateFromVkVertexInputRate(VkVertexInputRate rate) {
switch (rate) {
case VK_VERTEX_INPUT_RATE_VERTEX: return GPU_VERTEX_INPUT_RATE_VERTEX;
case VK_VERTEX_INPUT_RATE_INSTANCE: return GPU_VERTEX_INPUT_RATE_INSTANCE;
default: return GPU_VERTEX_INPUT_RATE_VERTEX;
}
}
wp_intern VkPrimitiveTopology vkPrimitiveTopologyFromGpuPrimitiveTopology(GpuPrimitiveTopology topology) {
switch (topology) {
case GPU_PRIMITIVE_TOPOLOGY_POINT_LIST: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case GPU_PRIMITIVE_TOPOLOGY_LINE_LIST: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case GPU_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case GPU_PRIMITIVE_TOPOLOGY_PATCH_LIST: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
}
}
wp_intern GpuPrimitiveTopology gpuPrimitiveTopologyFromVkPrimitiveTopology(VkPrimitiveTopology topology) {
switch (topology) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: return GPU_PRIMITIVE_TOPOLOGY_POINT_LIST;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: return GPU_PRIMITIVE_TOPOLOGY_LINE_LIST;
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return GPU_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: return GPU_PRIMITIVE_TOPOLOGY_PATCH_LIST;
default: return GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
}
}
wp_intern VkPolygonMode vkPolygonModeFromGpuPolygonMode(GpuPolygonMode mode) {
switch (mode) {
case GPU_POLYGON_MODE_FILL: return VK_POLYGON_MODE_FILL;
case GPU_POLYGON_MODE_LINE: return VK_POLYGON_MODE_LINE;
case GPU_POLYGON_MODE_POINT: return VK_POLYGON_MODE_POINT;
}
}
wp_intern GpuPolygonMode gpuPolygonModeFromVkPolygonMode(VkPolygonMode mode) {
switch (mode) {
case VK_POLYGON_MODE_FILL: return GPU_POLYGON_MODE_FILL;
case VK_POLYGON_MODE_LINE: return GPU_POLYGON_MODE_LINE;
case VK_POLYGON_MODE_POINT: return GPU_POLYGON_MODE_POINT;
default: return GPU_POLYGON_MODE_FILL;
}
}
wp_intern VkCullModeFlags vkCullModeFromGpuCullMode(GpuCullMode mode) {
switch (mode) {
case GPU_CULL_MODE_NONE: return VK_CULL_MODE_NONE;
case GPU_CULL_MODE_FRONT: return VK_CULL_MODE_FRONT_BIT;
case GPU_CULL_MODE_BACK: return VK_CULL_MODE_BACK_BIT;
case GPU_CULL_MODE_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK;
}
}
wp_intern GpuCullMode gpuCullModeFromVkCullMode(VkCullModeFlags mode) {
switch (mode) {
case VK_CULL_MODE_NONE: return GPU_CULL_MODE_NONE;
case VK_CULL_MODE_FRONT_BIT: return GPU_CULL_MODE_FRONT;
case VK_CULL_MODE_BACK_BIT: return GPU_CULL_MODE_BACK;
case VK_CULL_MODE_FRONT_AND_BACK: return GPU_CULL_MODE_FRONT_AND_BACK;
default: return GPU_CULL_MODE_NONE;
}
}
wp_intern VkFrontFace vkFrontFaceFromGpuFrontFace(GpuFrontFace front_face) {
switch (front_face) {
case GPU_FRONT_FACE_COUNTER_CLOCKWISE: return VK_FRONT_FACE_COUNTER_CLOCKWISE;
case GPU_FRONT_FACE_CLOCKWISE: return VK_FRONT_FACE_CLOCKWISE;
}
}
wp_intern GpuFrontFace gpuFrontFaceFromVkFrontFace(VkFrontFace front_face) {
switch (front_face) {
case VK_FRONT_FACE_COUNTER_CLOCKWISE: return GPU_FRONT_FACE_COUNTER_CLOCKWISE;
case VK_FRONT_FACE_CLOCKWISE: return GPU_FRONT_FACE_CLOCKWISE;
default: return GPU_FRONT_FACE_COUNTER_CLOCKWISE;
}
}
wp_intern VkStencilOp vkStencilOpFromGpuStencil(GpuStencilOp op) {
switch (op) {
case GPU_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP;
case GPU_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO;
case GPU_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE;
case GPU_STENCIL_OP_INCREMENT_AND_CLAMP: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
case GPU_STENCIL_OP_DECREMENT_AND_CLAMP: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
case GPU_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT;
case GPU_STENCIL_OP_INCREMENT_AND_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
case GPU_STENCIL_OP_DECREMENT_AND_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
}
}
wp_intern GpuStencilOp gpuStencilOpFromVkStencil(VkStencilOp op) {
switch (op) {
case VK_STENCIL_OP_KEEP: return GPU_STENCIL_OP_KEEP;
case VK_STENCIL_OP_ZERO: return GPU_STENCIL_OP_ZERO;
case VK_STENCIL_OP_REPLACE: return GPU_STENCIL_OP_REPLACE;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return GPU_STENCIL_OP_INCREMENT_AND_CLAMP;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return GPU_STENCIL_OP_DECREMENT_AND_CLAMP;
case VK_STENCIL_OP_INVERT: return GPU_STENCIL_OP_INVERT;
case VK_STENCIL_OP_INCREMENT_AND_WRAP: return GPU_STENCIL_OP_INCREMENT_AND_WRAP;
case VK_STENCIL_OP_DECREMENT_AND_WRAP: return GPU_STENCIL_OP_DECREMENT_AND_WRAP;
default: return GPU_STENCIL_OP_KEEP;
}
}
wp_intern VkBlendFactor vkBlendFactorFromGpuBlendFactor(GpuBlendFactor factor) {
switch (factor) {
case GPU_BLEND_FACTOR_ZERO: return VK_BLEND_FACTOR_ZERO;
case GPU_BLEND_FACTOR_ONE: return VK_BLEND_FACTOR_ONE;
case GPU_BLEND_FACTOR_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR;
case GPU_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case GPU_BLEND_FACTOR_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR;
case GPU_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
case GPU_BLEND_FACTOR_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA;
case GPU_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
case GPU_BLEND_FACTOR_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA;
case GPU_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
case GPU_BLEND_FACTOR_CONSTANT_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR;
case GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
case GPU_BLEND_FACTOR_CONSTANT_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA;
case GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
case GPU_BLEND_FACTOR_SRC_ALPHA_SATURATE: return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
case GPU_BLEND_FACTOR_SRC1_COLOR: return VK_BLEND_FACTOR_SRC1_COLOR;
case GPU_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
case GPU_BLEND_FACTOR_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA;
case GPU_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
}
}
wp_intern GpuBlendFactor gpuBlendFactorFromVkBlendFactor(VkBlendFactor factor) {
switch (factor) {
case VK_BLEND_FACTOR_ZERO: return GPU_BLEND_FACTOR_ZERO;
case VK_BLEND_FACTOR_ONE: return GPU_BLEND_FACTOR_ONE;
case VK_BLEND_FACTOR_SRC_COLOR: return GPU_BLEND_FACTOR_SRC_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: return GPU_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case VK_BLEND_FACTOR_DST_COLOR: return GPU_BLEND_FACTOR_DST_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return GPU_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
case VK_BLEND_FACTOR_SRC_ALPHA: return GPU_BLEND_FACTOR_SRC_ALPHA;
case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return GPU_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
case VK_BLEND_FACTOR_DST_ALPHA: return GPU_BLEND_FACTOR_DST_ALPHA;
case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return GPU_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
case VK_BLEND_FACTOR_CONSTANT_COLOR: return GPU_BLEND_FACTOR_CONSTANT_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: return GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
case VK_BLEND_FACTOR_CONSTANT_ALPHA: return GPU_BLEND_FACTOR_CONSTANT_ALPHA;
case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: return GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: return GPU_BLEND_FACTOR_SRC_ALPHA_SATURATE;
case VK_BLEND_FACTOR_SRC1_COLOR: return GPU_BLEND_FACTOR_SRC1_COLOR;
case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: return GPU_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
case VK_BLEND_FACTOR_SRC1_ALPHA: return GPU_BLEND_FACTOR_SRC1_ALPHA;
case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: return GPU_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
default: return GPU_BLEND_FACTOR_ZERO;
}
}
wp_intern VkBlendOp vkBlendOpFromGpuBlendOp(GpuBlendOp op) {
switch (op) {
case GPU_BLEND_OP_ADD: return VK_BLEND_OP_ADD;
case GPU_BLEND_OP_SUBTRACT: return VK_BLEND_OP_SUBTRACT;
case GPU_BLEND_OP_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
case GPU_BLEND_OP_MIN: return VK_BLEND_OP_MIN;
case GPU_BLEND_OP_MAX: return VK_BLEND_OP_MAX;
}
}
wp_intern GpuBlendOp gpuBlendOpFromVkBlendOp(VkBlendOp op) {
switch (op) {
case VK_BLEND_OP_ADD: return GPU_BLEND_OP_ADD;
case VK_BLEND_OP_SUBTRACT: return GPU_BLEND_OP_SUBTRACT;
case VK_BLEND_OP_REVERSE_SUBTRACT: return GPU_BLEND_OP_REVERSE_SUBTRACT;
case VK_BLEND_OP_MIN: return GPU_BLEND_OP_MIN;
case VK_BLEND_OP_MAX: return GPU_BLEND_OP_MAX;
default: return GPU_BLEND_OP_ADD;
}
}
wp_intern VkColorComponentFlags vkColorComponentFlagsFromGpuColorComponentFlags(GpuColorComponentFlags flags) {
VkColorComponentFlags output = 0;
output |= (flags & GPU_COLOR_COMPONENT_R) != 0 ? VK_COLOR_COMPONENT_R_BIT : 0;
output |= (flags & GPU_COLOR_COMPONENT_G) != 0 ? VK_COLOR_COMPONENT_G_BIT : 0;
output |= (flags & GPU_COLOR_COMPONENT_B) != 0 ? VK_COLOR_COMPONENT_B_BIT : 0;
output |= (flags & GPU_COLOR_COMPONENT_A) != 0 ? VK_COLOR_COMPONENT_A_BIT : 0;
return output;
}
wp_intern GpuColorComponentFlags gpuColorComponentFlagsFromVkColorComponentFlags(VkColorComponentFlags flags) {
GpuColorComponentFlags output = 0;
output |= (flags & VK_COLOR_COMPONENT_R_BIT) != 0 ? GPU_COLOR_COMPONENT_R : 0;
output |= (flags & VK_COLOR_COMPONENT_G_BIT) != 0 ? GPU_COLOR_COMPONENT_G : 0;
output |= (flags & VK_COLOR_COMPONENT_B_BIT) != 0 ? GPU_COLOR_COMPONENT_B : 0;
output |= (flags & VK_COLOR_COMPONENT_A_BIT) != 0 ? GPU_COLOR_COMPONENT_A : 0;
return output;
}
wp_intern VkLogicOp vkLogicOpFromGpuLogicOp(GpuLogicOp op) {
switch (op) {
case GPU_LOGIC_OP_CLEAR: return VK_LOGIC_OP_CLEAR;
case GPU_LOGIC_OP_AND: return VK_LOGIC_OP_AND;
case GPU_LOGIC_OP_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE;
case GPU_LOGIC_OP_COPY: return VK_LOGIC_OP_COPY;
case GPU_LOGIC_OP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
case GPU_LOGIC_OP_NO_OP: return VK_LOGIC_OP_NO_OP;
case GPU_LOGIC_OP_XOR: return VK_LOGIC_OP_XOR;
case GPU_LOGIC_OP_OR: return VK_LOGIC_OP_OR;
case GPU_LOGIC_OP_NOR: return VK_LOGIC_OP_NOR;
case GPU_LOGIC_OP_EQUIVALENT: return VK_LOGIC_OP_EQUIVALENT;
case GPU_LOGIC_OP_INVERT: return VK_LOGIC_OP_INVERT;
case GPU_LOGIC_OP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
case GPU_LOGIC_OP_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED;
case GPU_LOGIC_OP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
case GPU_LOGIC_OP_NAND: return VK_LOGIC_OP_NAND;
case GPU_LOGIC_OP_SET: return VK_LOGIC_OP_SET;
}
}
wp_intern GpuLogicOp gpuLogicOpFromVkLogicOp(VkLogicOp op) {
switch (op) {
case VK_LOGIC_OP_CLEAR: return GPU_LOGIC_OP_CLEAR;
case VK_LOGIC_OP_AND: return GPU_LOGIC_OP_AND;
case VK_LOGIC_OP_AND_REVERSE: return GPU_LOGIC_OP_AND_REVERSE;
case VK_LOGIC_OP_COPY: return GPU_LOGIC_OP_COPY;
case VK_LOGIC_OP_AND_INVERTED: return GPU_LOGIC_OP_AND_INVERTED;
case VK_LOGIC_OP_NO_OP: return GPU_LOGIC_OP_NO_OP;
case VK_LOGIC_OP_XOR: return GPU_LOGIC_OP_XOR;
case VK_LOGIC_OP_OR: return GPU_LOGIC_OP_OR;
case VK_LOGIC_OP_NOR: return GPU_LOGIC_OP_NOR;
case VK_LOGIC_OP_EQUIVALENT: return GPU_LOGIC_OP_EQUIVALENT;
case VK_LOGIC_OP_INVERT: return GPU_LOGIC_OP_INVERT;
case VK_LOGIC_OP_OR_REVERSE: return GPU_LOGIC_OP_OR_REVERSE;
case VK_LOGIC_OP_COPY_INVERTED: return GPU_LOGIC_OP_COPY_INVERTED;
case VK_LOGIC_OP_OR_INVERTED: return GPU_LOGIC_OP_OR_INVERTED;
case VK_LOGIC_OP_NAND: return GPU_LOGIC_OP_NAND;
case VK_LOGIC_OP_SET: return GPU_LOGIC_OP_SET;
default: return GPU_LOGIC_OP_CLEAR;
}
}