Files
SDL/src/render/vulkan/SDL_render_vulkan.c

4177 lines
191 KiB
C
Raw Normal View History

Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_VULKAN
#define SDL_VULKAN_FRAME_QUEUE_DEPTH 2
#define SDL_VULKAN_NUM_VERTEX_BUFFERS 256
#define SDL_VULKAN_VERTEX_BUFFER_DEFAULT_SIZE 65536
#define SDL_VULKAN_CONSTANT_BUFFER_DEFAULT_SIZE 65536
#define SDL_VULKAN_NUM_UPLOAD_BUFFERS 32
#define SDL_VULKAN_MAX_DESCRIPTOR_SETS 4096
#define SDL_VULKAN_VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
#define VK_NO_PROTOTYPES
#include "../../video/SDL_vulkan_internal.h"
#include "../../video/SDL_sysvideo.h"
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
#include "../SDL_sysrender.h"
#include "../SDL_d3dmath.h"
#include "../../video/SDL_pixels_c.h"
#include "SDL_shaders_vulkan.h"
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
extern const char *SDL_Vulkan_GetResultString(VkResult result);
#define VULKAN_FUNCTIONS() \
VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR) \
VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers) \
VULKAN_DEVICE_FUNCTION(vkAllocateDescriptorSets) \
VULKAN_DEVICE_FUNCTION(vkAllocateMemory) \
VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer) \
VULKAN_DEVICE_FUNCTION(vkBindBufferMemory) \
VULKAN_DEVICE_FUNCTION(vkBindImageMemory) \
VULKAN_DEVICE_FUNCTION(vkCmdBeginRenderPass) \
VULKAN_DEVICE_FUNCTION(vkCmdBindDescriptorSets) \
VULKAN_DEVICE_FUNCTION(vkCmdBindPipeline) \
VULKAN_DEVICE_FUNCTION(vkCmdBindVertexBuffers) \
VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage) \
VULKAN_DEVICE_FUNCTION(vkCmdCopyBufferToImage) \
VULKAN_DEVICE_FUNCTION(vkCmdCopyImageToBuffer) \
VULKAN_DEVICE_FUNCTION(vkCmdDraw) \
VULKAN_DEVICE_FUNCTION(vkCmdEndRenderPass) \
VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier) \
VULKAN_DEVICE_FUNCTION(vkCmdPushConstants) \
VULKAN_DEVICE_FUNCTION(vkCmdSetScissor) \
VULKAN_DEVICE_FUNCTION(vkCmdSetViewport) \
VULKAN_DEVICE_FUNCTION(vkCreateBuffer) \
VULKAN_DEVICE_FUNCTION(vkCreateCommandPool) \
VULKAN_DEVICE_FUNCTION(vkCreateDescriptorPool) \
VULKAN_DEVICE_FUNCTION(vkCreateDescriptorSetLayout) \
VULKAN_DEVICE_FUNCTION(vkCreateFence) \
VULKAN_DEVICE_FUNCTION(vkCreateFramebuffer) \
VULKAN_DEVICE_FUNCTION(vkCreateGraphicsPipelines) \
VULKAN_DEVICE_FUNCTION(vkCreateImage) \
VULKAN_DEVICE_FUNCTION(vkCreateImageView) \
VULKAN_DEVICE_FUNCTION(vkCreatePipelineLayout) \
VULKAN_DEVICE_FUNCTION(vkCreateRenderPass) \
VULKAN_DEVICE_FUNCTION(vkCreateSampler) \
VULKAN_DEVICE_FUNCTION(vkCreateSemaphore) \
VULKAN_DEVICE_FUNCTION(vkCreateShaderModule) \
VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR) \
VULKAN_DEVICE_FUNCTION(vkDestroyBuffer) \
VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool) \
VULKAN_DEVICE_FUNCTION(vkDestroyDevice) \
VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorPool) \
VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout) \
VULKAN_DEVICE_FUNCTION(vkDestroyFence) \
VULKAN_DEVICE_FUNCTION(vkDestroyFramebuffer) \
VULKAN_DEVICE_FUNCTION(vkDestroyImage) \
VULKAN_DEVICE_FUNCTION(vkDestroyImageView) \
VULKAN_DEVICE_FUNCTION(vkDestroyPipeline) \
VULKAN_DEVICE_FUNCTION(vkDestroyPipelineLayout) \
VULKAN_DEVICE_FUNCTION(vkDestroyRenderPass) \
VULKAN_DEVICE_FUNCTION(vkDestroySampler) \
VULKAN_DEVICE_FUNCTION(vkDestroySemaphore) \
VULKAN_DEVICE_FUNCTION(vkDestroyShaderModule) \
VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR) \
VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle) \
VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer) \
VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers) \
VULKAN_DEVICE_FUNCTION(vkFreeMemory) \
VULKAN_DEVICE_FUNCTION(vkGetBufferMemoryRequirements) \
VULKAN_DEVICE_FUNCTION(vkGetImageMemoryRequirements) \
VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue) \
VULKAN_DEVICE_FUNCTION(vkGetFenceStatus) \
VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR) \
VULKAN_DEVICE_FUNCTION(vkMapMemory) \
VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR) \
VULKAN_DEVICE_FUNCTION(vkQueueSubmit) \
VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer) \
VULKAN_DEVICE_FUNCTION(vkResetCommandPool) \
VULKAN_DEVICE_FUNCTION(vkResetDescriptorPool) \
VULKAN_DEVICE_FUNCTION(vkResetFences) \
VULKAN_DEVICE_FUNCTION(vkUnmapMemory) \
VULKAN_DEVICE_FUNCTION(vkUpdateDescriptorSets) \
VULKAN_DEVICE_FUNCTION(vkWaitForFences) \
VULKAN_GLOBAL_FUNCTION(vkCreateInstance) \
VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties) \
VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties) \
VULKAN_INSTANCE_FUNCTION(vkCreateDevice) \
VULKAN_INSTANCE_FUNCTION(vkDestroyInstance) \
VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR) \
VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties) \
VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices) \
VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) \
VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) \
VULKAN_INSTANCE_FUNCTION(vkQueueWaitIdle) \
VULKAN_OPTIONAL_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures2KHR) \
VULKAN_OPTIONAL_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties2KHR) \
VULKAN_OPTIONAL_INSTANCE_FUNCTION(vkGetPhysicalDeviceImageFormatProperties2KHR) \
VULKAN_OPTIONAL_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties2KHR) \
VULKAN_OPTIONAL_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties2KHR) \
VULKAN_OPTIONAL_DEVICE_FUNCTION(vkCreateSamplerYcbcrConversionKHR) \
VULKAN_OPTIONAL_DEVICE_FUNCTION(vkDestroySamplerYcbcrConversionKHR) \
#define VULKAN_DEVICE_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_GLOBAL_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_INSTANCE_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name) static PFN_##name name = NULL;
#define VULKAN_OPTIONAL_DEVICE_FUNCTION(name) static PFN_##name name = NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_DEVICE_FUNCTION
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Renderpass types
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef enum {
SDL_VULKAN_RENDERPASS_LOAD = 0,
SDL_VULKAN_RENDERPASS_CLEAR = 1,
SDL_VULKAN_NUM_RENDERPASSES
} SDL_vulkan_renderpass_type;
// Sampler types
typedef enum
{
SDL_VULKAN_SAMPLER_NEAREST_CLAMP,
SDL_VULKAN_SAMPLER_NEAREST_WRAP,
SDL_VULKAN_SAMPLER_LINEAR_CLAMP,
SDL_VULKAN_SAMPLER_LINEAR_WRAP,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_VULKAN_NUM_SAMPLERS
} SDL_vulkan_sampler_type;
// Vertex shader, common values
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
Float4X4 model;
Float4X4 projectionAndView;
} VertexShaderConstants;
// These should mirror the definitions in VULKAN_PixelShader_Common.hlsli
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
//static const float TONEMAP_NONE = 0;
//static const float TONEMAP_LINEAR = 1;
static const float TONEMAP_CHROME = 2;
static const float INPUTTYPE_UNSPECIFIED = 0;
static const float INPUTTYPE_SRGB = 1;
static const float INPUTTYPE_SCRGB = 2;
static const float INPUTTYPE_HDR10 = 3;
typedef enum
{
SAMPLER_POINT_CLAMP,
SAMPLER_POINT_WRAP,
SAMPLER_LINEAR_CLAMP,
SAMPLER_LINEAR_WRAP,
NUM_SAMPLERS
} Sampler;
// Pixel shader constants, common values
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
float scRGB_output;
float input_type;
float color_scale;
float unused_pad0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
float tonemap_method;
float tonemap_factor1;
float tonemap_factor2;
float sdr_white_point;
} PixelShaderConstants;
// Per-vertex data
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
float pos[2];
float tex[2];
SDL_FColor color;
} VertexPositionColor;
// Vulkan Buffer
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
VkDeviceMemory deviceMemory;
VkBuffer buffer;
VkDeviceSize size;
void *mappedBufferPtr;
} VULKAN_Buffer;
// Vulkan image
typedef struct
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
2024-08-22 09:21:26 -07:00
bool allocatedImage;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkImage image;
VkImageView imageView;
VkDeviceMemory deviceMemory;
VkImageLayout imageLayout;
VkFormat format;
} VULKAN_Image;
// Per-texture data
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
VULKAN_Image mainImage;
VkRenderPass mainRenderpasses[SDL_VULKAN_NUM_RENDERPASSES];
VkFramebuffer mainFramebuffer;
VULKAN_Buffer stagingBuffer;
VkFilter scaleMode;
SDL_Rect lockedRect;
int width;
int height;
VULKAN_Shader shader;
// Object passed to VkImageView and VkSampler for doing Ycbcr -> RGB conversion
VkSamplerYcbcrConversion samplerYcbcrConversion;
// Sampler created with samplerYcbcrConversion, passed to PSO as immutable sampler
VkSampler samplerYcbcr;
// Descriptor set layout with samplerYcbcr baked as immutable sampler
VkDescriptorSetLayout descriptorSetLayoutYcbcr;
// Pipeline layout with immutable sampler descriptor set layout
VkPipelineLayout pipelineLayoutYcbcr;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
} VULKAN_TextureData;
// Pipeline State Object data
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
VULKAN_Shader shader;
PixelShaderConstants shader_constants;
SDL_BlendMode blendMode;
VkPrimitiveTopology topology;
VkFormat format;
VkPipelineLayout pipelineLayout;
VkDescriptorSetLayout descriptorSetLayout;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkPipeline pipeline;
} VULKAN_PipelineState;
typedef struct
{
VkBuffer vertexBuffer;
} VULKAN_DrawStateCache;
// Private renderer data
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
typedef struct
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
VkInstance instance;
2024-08-22 09:21:26 -07:00
bool instance_external;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkSurfaceKHR surface;
2024-08-22 09:21:26 -07:00
bool surface_external;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkPhysicalDevice physicalDevice;
VkPhysicalDeviceProperties physicalDeviceProperties;
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
VkPhysicalDeviceFeatures physicalDeviceFeatures;
VkQueue graphicsQueue;
VkQueue presentQueue;
VkDevice device;
2024-08-22 09:21:26 -07:00
bool device_external;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uint32_t graphicsQueueFamilyIndex;
uint32_t presentQueueFamilyIndex;
VkSwapchainKHR swapchain;
VkCommandPool commandPool;
VkCommandBuffer *commandBuffers;
uint32_t currentCommandBufferIndex;
VkCommandBuffer currentCommandBuffer;
VkFence *fences;
VkSurfaceCapabilitiesKHR surfaceCapabilities;
VkSurfaceFormatKHR *surfaceFormats;
2024-08-22 09:21:26 -07:00
bool recreateSwapchain;
int vsync;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkFramebuffer *framebuffers;
VkRenderPass renderPasses[SDL_VULKAN_NUM_RENDERPASSES];
VkRenderPass currentRenderPass;
VkShaderModule vertexShaderModules[NUM_SHADERS];
VkShaderModule fragmentShaderModules[NUM_SHADERS];
VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Vertex buffer data
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_Buffer vertexBuffers[SDL_VULKAN_NUM_VERTEX_BUFFERS];
VertexShaderConstants vertexShaderConstantsData;
// Data for staging/allocating textures
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_Buffer **uploadBuffers;
int *currentUploadBuffer;
// Data for updating constants
VULKAN_Buffer **constantBuffers;
uint32_t *numConstantBuffers;
uint32_t currentConstantBufferIndex;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
int32_t currentConstantBufferOffset;
VkSampler samplers[SDL_VULKAN_NUM_SAMPLERS];
VkDescriptorPool **descriptorPools;
uint32_t *numDescriptorPools;
uint32_t currentDescriptorPoolIndex;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uint32_t currentDescriptorSetIndex;
int pipelineStateCount;
VULKAN_PipelineState *pipelineStates;
VULKAN_PipelineState *currentPipelineState;
2024-08-22 09:21:26 -07:00
bool supportsEXTSwapchainColorspace;
bool supportsKHRGetPhysicalDeviceProperties2;
bool supportsKHRSamplerYCbCrConversion;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uint32_t surfaceFormatsAllocatedCount;
uint32_t surfaceFormatsCount;
uint32_t swapchainDesiredImageCount;
VkSurfaceFormatKHR surfaceFormat;
VkExtent2D swapchainSize;
uint32_t swapchainImageCount;
VkImage *swapchainImages;
VkImageView *swapchainImageViews;
VkImageLayout *swapchainImageLayouts;
VkSemaphore *imageAvailableSemaphores;
VkSemaphore *renderingFinishedSemaphores;
VkSemaphore currentImageAvailableSemaphore;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uint32_t currentSwapchainImageIndex;
VkPipelineStageFlags *waitDestStageMasks;
VkSemaphore *waitRenderSemaphores;
uint32_t waitRenderSemaphoreCount;
uint32_t waitRenderSemaphoreMax;
VkSemaphore *signalRenderSemaphores;
uint32_t signalRenderSemaphoreCount;
uint32_t signalRenderSemaphoreMax;
// Cached renderer properties
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_TextureData *textureRenderTarget;
2024-08-22 09:21:26 -07:00
bool cliprectDirty;
bool currentCliprectEnabled;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_Rect currentCliprect;
SDL_Rect currentViewport;
int currentViewportRotation;
2024-08-22 09:21:26 -07:00
bool viewportDirty;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
Float4X4 identity;
VkComponentMapping identitySwizzle;
int currentVertexBuffer;
2024-08-22 09:21:26 -07:00
bool issueBatch;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
} VULKAN_RenderData;
static SDL_PixelFormat VULKAN_VkFormatToSDLPixelFormat(VkFormat vkFormat)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
switch (vkFormat) {
case VK_FORMAT_B8G8R8A8_UNORM:
return SDL_PIXELFORMAT_ARGB8888;
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
return SDL_PIXELFORMAT_XBGR2101010;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return SDL_PIXELFORMAT_RGBA64_FLOAT;
default:
return SDL_PIXELFORMAT_UNKNOWN;
}
}
static int VULKAN_VkFormatGetNumPlanes(VkFormat vkFormat)
{
switch (vkFormat) {
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
return 3;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
return 2;
default:
return 1;
}
}
static VkDeviceSize VULKAN_GetBytesPerPixel(VkFormat vkFormat)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
switch (vkFormat) {
case VK_FORMAT_R8_UNORM:
return 1;
case VK_FORMAT_R8G8_UNORM:
return 2;
case VK_FORMAT_R16G16_UNORM:
return 4;
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
return 4;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return 8;
default:
return 4;
}
}
static VkFormat SDLPixelFormatToVkTextureFormat(Uint32 format, Uint32 colorspace)
{
switch (format) {
case SDL_PIXELFORMAT_RGBA64_FLOAT:
return VK_FORMAT_R16G16B16A16_SFLOAT;
case SDL_PIXELFORMAT_XBGR2101010:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case SDL_PIXELFORMAT_ARGB8888:
case SDL_PIXELFORMAT_XRGB8888:
if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
return VK_FORMAT_B8G8R8A8_SRGB;
}
return VK_FORMAT_B8G8R8A8_UNORM;
case SDL_PIXELFORMAT_YUY2:
return VK_FORMAT_G8B8G8R8_422_UNORM;
case SDL_PIXELFORMAT_UYVY:
return VK_FORMAT_B8G8R8G8_422_UNORM;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
case SDL_PIXELFORMAT_P010:
return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
default:
return VK_FORMAT_UNDEFINED;
}
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static void VULKAN_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static void VULKAN_DestroyBuffer(VULKAN_RenderData *rendererData, VULKAN_Buffer *vulkanBuffer);
static void VULKAN_DestroyImage(VULKAN_RenderData *rendererData, VULKAN_Image *vulkanImage);
static void VULKAN_ResetCommandList(VULKAN_RenderData *rendererData);
2024-08-22 09:21:26 -07:00
static bool VULKAN_FindMemoryTypeIndex(VULKAN_RenderData *rendererData, uint32_t typeBits, VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags desiredFlags, uint32_t *memoryTypeIndexOut);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static VkResult VULKAN_CreateWindowSizeDependentResources(SDL_Renderer *renderer);
static VkDescriptorPool VULKAN_AllocateDescriptorPool(VULKAN_RenderData *rendererData);
static VkResult VULKAN_CreateDescriptorSetAndPipelineLayout(VULKAN_RenderData *rendererData, VkSampler samplerYcbcr, VkDescriptorSetLayout *descriptorSetLayoutOut, VkPipelineLayout *pipelineLayoutOut);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static void VULKAN_DestroyAll(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData;
if (renderer == NULL) {
return;
}
rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData == NULL) {
return;
}
if (rendererData->waitDestStageMasks) {
SDL_free(rendererData->waitDestStageMasks);
rendererData->waitDestStageMasks = NULL;
}
if (rendererData->waitRenderSemaphores) {
SDL_free(rendererData->waitRenderSemaphores);
rendererData->waitRenderSemaphores = NULL;
}
if (rendererData->signalRenderSemaphores) {
SDL_free(rendererData->signalRenderSemaphores);
rendererData->signalRenderSemaphores = NULL;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->surfaceFormats != NULL) {
SDL_free(rendererData->surfaceFormats);
rendererData->surfaceFormats = NULL;
}
if (rendererData->swapchainImages != NULL) {
SDL_free(rendererData->swapchainImages);
rendererData->swapchainImages = NULL;
}
if (rendererData->swapchain) {
vkDestroySwapchainKHR(rendererData->device, rendererData->swapchain, NULL);
rendererData->swapchain = VK_NULL_HANDLE;
}
if (rendererData->fences != NULL) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->fences[i] != VK_NULL_HANDLE) {
vkDestroyFence(rendererData->device, rendererData->fences[i], NULL);
rendererData->fences[i] = VK_NULL_HANDLE;
}
}
SDL_free(rendererData->fences);
rendererData->fences = NULL;
}
if (rendererData->swapchainImageViews) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->swapchainImageViews[i] != VK_NULL_HANDLE) {
vkDestroyImageView(rendererData->device, rendererData->swapchainImageViews[i], NULL);
}
}
SDL_free(rendererData->swapchainImageViews);
rendererData->swapchainImageViews = NULL;
}
if (rendererData->swapchainImageLayouts) {
SDL_free(rendererData->swapchainImageLayouts);
rendererData->swapchainImageLayouts = NULL;
}
if (rendererData->framebuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->framebuffers[i] != VK_NULL_HANDLE) {
vkDestroyFramebuffer(rendererData->device, rendererData->framebuffers[i], NULL);
}
}
SDL_free(rendererData->framebuffers);
rendererData->framebuffers = NULL;
}
for (uint32_t i = 0; i < SDL_arraysize(rendererData->samplers); i++) {
if (rendererData->samplers[i] != VK_NULL_HANDLE) {
vkDestroySampler(rendererData->device, rendererData->samplers[i], NULL);
rendererData->samplers[i] = VK_NULL_HANDLE;
}
}
for (uint32_t i = 0; i < SDL_arraysize(rendererData->vertexBuffers); i++ ) {
VULKAN_DestroyBuffer(rendererData, &rendererData->vertexBuffers[i]);
}
SDL_memset(rendererData->vertexBuffers, 0, sizeof(rendererData->vertexBuffers));
for (uint32_t i = 0; i < SDL_VULKAN_NUM_RENDERPASSES; i++) {
if (rendererData->renderPasses[i] != VK_NULL_HANDLE) {
vkDestroyRenderPass(rendererData->device, rendererData->renderPasses[i], NULL);
rendererData->renderPasses[i] = VK_NULL_HANDLE;
}
}
if (rendererData->imageAvailableSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->imageAvailableSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->imageAvailableSemaphores[i], NULL);
}
}
SDL_free(rendererData->imageAvailableSemaphores);
rendererData->imageAvailableSemaphores = NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->renderingFinishedSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->renderingFinishedSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->renderingFinishedSemaphores[i], NULL);
}
}
SDL_free(rendererData->renderingFinishedSemaphores);
rendererData->renderingFinishedSemaphores = NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->commandPool) {
if (rendererData->commandBuffers) {
vkFreeCommandBuffers(rendererData->device, rendererData->commandPool, rendererData->swapchainImageCount, rendererData->commandBuffers);
SDL_free(rendererData->commandBuffers);
rendererData->commandBuffers = NULL;
}
vkDestroyCommandPool(rendererData->device, rendererData->commandPool, NULL);
rendererData->commandPool = VK_NULL_HANDLE;
}
if (rendererData->descriptorPools) {
SDL_assert(rendererData->numDescriptorPools);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < rendererData->numDescriptorPools[i]; j++) {
if (rendererData->descriptorPools[i][j] != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(rendererData->device, rendererData->descriptorPools[i][j], NULL);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->descriptorPools[i]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->descriptorPools);
SDL_free(rendererData->numDescriptorPools);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
for (uint32_t i = 0; i < NUM_SHADERS; i++) {
if (rendererData->vertexShaderModules[i] != VK_NULL_HANDLE) {
vkDestroyShaderModule(rendererData->device, rendererData->vertexShaderModules[i], NULL);
rendererData->vertexShaderModules[i] = VK_NULL_HANDLE;
}
if (rendererData->fragmentShaderModules[i] != VK_NULL_HANDLE) {
vkDestroyShaderModule(rendererData->device, rendererData->fragmentShaderModules[i], NULL);
rendererData->fragmentShaderModules[i] = VK_NULL_HANDLE;
}
}
if (rendererData->descriptorSetLayout != VK_NULL_HANDLE) {
vkDestroyDescriptorSetLayout(rendererData->device, rendererData->descriptorSetLayout, NULL);
rendererData->descriptorSetLayout = VK_NULL_HANDLE;
}
if (rendererData->pipelineLayout != VK_NULL_HANDLE) {
vkDestroyPipelineLayout(rendererData->device, rendererData->pipelineLayout, NULL);
rendererData->pipelineLayout = VK_NULL_HANDLE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
for (int i = 0; i < rendererData->pipelineStateCount; i++) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkDestroyPipeline(rendererData->device, rendererData->pipelineStates[i].pipeline, NULL);
}
SDL_free(rendererData->pipelineStates);
rendererData->pipelineStateCount = 0;
if (rendererData->currentUploadBuffer) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
for (int j = 0; j < rendererData->currentUploadBuffer[i]; ++j) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyBuffer(rendererData, &rendererData->uploadBuffers[i][j]);
}
SDL_free(rendererData->uploadBuffers[i]);
}
SDL_free(rendererData->uploadBuffers);
SDL_free(rendererData->currentUploadBuffer);
}
if (rendererData->constantBuffers) {
SDL_assert(rendererData->numConstantBuffers);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
for (uint32_t j = 0; j < rendererData->numConstantBuffers[i]; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->constantBuffers[i][j]);
}
SDL_free(rendererData->constantBuffers[i]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->constantBuffers);
SDL_free(rendererData->numConstantBuffers);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->constantBuffers = NULL;
}
if (rendererData->device != VK_NULL_HANDLE && !rendererData->device_external) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkDestroyDevice(rendererData->device, NULL);
rendererData->device = VK_NULL_HANDLE;
}
if (rendererData->surface != VK_NULL_HANDLE && !rendererData->surface_external) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkDestroySurfaceKHR(rendererData->instance, rendererData->surface, NULL);
rendererData->surface = VK_NULL_HANDLE;
}
if (rendererData->instance != VK_NULL_HANDLE && !rendererData->instance_external) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkDestroyInstance(rendererData->instance, NULL);
rendererData->instance = VK_NULL_HANDLE;
}
}
static void VULKAN_DestroyBuffer(VULKAN_RenderData *rendererData, VULKAN_Buffer *vulkanBuffer)
{
if (vulkanBuffer->buffer != VK_NULL_HANDLE) {
vkDestroyBuffer(rendererData->device, vulkanBuffer->buffer, NULL);
vulkanBuffer->buffer = VK_NULL_HANDLE;
}
if (vulkanBuffer->deviceMemory != VK_NULL_HANDLE) {
vkFreeMemory(rendererData->device, vulkanBuffer->deviceMemory, NULL);
vulkanBuffer->deviceMemory = VK_NULL_HANDLE;
}
SDL_memset(vulkanBuffer, 0, sizeof(VULKAN_Buffer));
}
static VkResult VULKAN_AllocateBuffer(VULKAN_RenderData *rendererData, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags requiredMemoryProps, VkMemoryPropertyFlags desiredMemoryProps, VULKAN_Buffer *bufferOut)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VkResult result;
VkBufferCreateInfo bufferCreateInfo = { 0 };
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferCreateInfo.size = size;
bufferCreateInfo.usage = usage;
result = vkCreateBuffer(rendererData->device, &bufferCreateInfo, NULL, &bufferOut->buffer);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateBuffer(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
VkMemoryRequirements memoryRequirements = { 0 };
vkGetBufferMemoryRequirements(rendererData->device, bufferOut->buffer, &memoryRequirements);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetBufferMemoryRequirements(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
uint32_t memoryTypeIndex = 0;
if (!VULKAN_FindMemoryTypeIndex(rendererData, memoryRequirements.memoryTypeBits, requiredMemoryProps, desiredMemoryProps, &memoryTypeIndex)) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyBuffer(rendererData, bufferOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_FindMemoryTypeIndex failed.\n");
return VK_ERROR_UNKNOWN;;
}
VkMemoryAllocateInfo memoryAllocateInfo = { 0 };
memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryAllocateInfo.allocationSize = memoryRequirements.size;
memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
result = vkAllocateMemory(rendererData->device, &memoryAllocateInfo, NULL, &bufferOut->deviceMemory);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAllocateMemory(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
result = vkBindBufferMemory(rendererData->device, bufferOut->buffer, bufferOut->deviceMemory, 0);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindBufferMemory(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
result = vkMapMemory(rendererData->device, bufferOut->deviceMemory, 0, size, 0, &bufferOut->mappedBufferPtr);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkMapMemory(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
bufferOut->size = size;
return result;
}
static void VULKAN_DestroyImage(VULKAN_RenderData *rendererData, VULKAN_Image *vulkanImage)
{
if (vulkanImage->imageView != VK_NULL_HANDLE) {
vkDestroyImageView(rendererData->device, vulkanImage->imageView, NULL);
vulkanImage->imageView = VK_NULL_HANDLE;
}
if (vulkanImage->image != VK_NULL_HANDLE) {
if (vulkanImage->allocatedImage) {
vkDestroyImage(rendererData->device, vulkanImage->image, NULL);
}
vulkanImage->image = VK_NULL_HANDLE;
}
if (vulkanImage->deviceMemory != VK_NULL_HANDLE) {
if (vulkanImage->allocatedImage) {
vkFreeMemory(rendererData->device, vulkanImage->deviceMemory, NULL);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vulkanImage->deviceMemory = VK_NULL_HANDLE;
}
SDL_memset(vulkanImage, 0, sizeof(VULKAN_Image));
}
static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_PropertiesID create_props, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags imageUsage, VkComponentMapping swizzle, VkSamplerYcbcrConversionKHR samplerYcbcrConversion, VULKAN_Image *imageOut)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VkResult result;
VkSamplerYcbcrConversionInfoKHR samplerYcbcrConversionInfo = { 0 };
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_memset(imageOut, 0, sizeof(VULKAN_Image));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
imageOut->format = format;
imageOut->image = (VkImage)SDL_GetNumberProperty(create_props, SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER, 0);
if (imageOut->image == VK_NULL_HANDLE) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
imageOut->allocatedImage = VK_TRUE;
VkImageCreateInfo imageCreateInfo = { 0 };
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.flags = 0;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = format;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = imageUsage;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.queueFamilyIndexCount = 0;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkCreateImage(rendererData->device, &imageCreateInfo, NULL, &imageOut->image);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateImage(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
VkMemoryRequirements memoryRequirements = { 0 };
vkGetImageMemoryRequirements(rendererData->device, imageOut->image, &memoryRequirements);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetImageMemoryRequirements(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
uint32_t memoryTypeIndex = 0;
if (!VULKAN_FindMemoryTypeIndex(rendererData, memoryRequirements.memoryTypeBits, 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memoryTypeIndex)) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_FindMemoryTypeIndex failed.\n");
return VK_ERROR_UNKNOWN;
}
VkMemoryAllocateInfo memoryAllocateInfo = { 0 };
memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryAllocateInfo.allocationSize = memoryRequirements.size;
memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
result = vkAllocateMemory(rendererData->device, &memoryAllocateInfo, NULL, &imageOut->deviceMemory);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAllocateMemory(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
result = vkBindImageMemory(rendererData->device, imageOut->image, imageOut->deviceMemory, 0);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindImageMemory(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
} else {
imageOut->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
VkImageViewCreateInfo imageViewCreateInfo = { 0 };
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.image = imageOut->image;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.format = format;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
imageViewCreateInfo.components = swizzle;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
// If it's a YCbCr image, we need to pass the conversion info to the VkImageView (and the VkSampler)
if (samplerYcbcrConversion != VK_NULL_HANDLE) {
samplerYcbcrConversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR;
samplerYcbcrConversionInfo.conversion = samplerYcbcrConversion;
imageViewCreateInfo.pNext = &samplerYcbcrConversionInfo;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkCreateImageView(rendererData->device, &imageViewCreateInfo, NULL, &imageOut->imageView);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateImageView(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
return result;
}
static void VULKAN_RecordPipelineImageBarrier(VULKAN_RenderData *rendererData, VkAccessFlags sourceAccessMask, VkAccessFlags destAccessMask,
VkPipelineStageFlags srcStageFlags, VkPipelineStageFlags dstStageFlags, VkImageLayout destLayout, VkImage image, VkImageLayout *imageLayout)
{
// Stop any outstanding renderpass if open
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->currentRenderPass != VK_NULL_HANDLE) {
vkCmdEndRenderPass(rendererData->currentCommandBuffer);
rendererData->currentRenderPass = VK_NULL_HANDLE;
}
VkImageMemoryBarrier barrier = { 0 };
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = sourceAccessMask;
barrier.dstAccessMask = destAccessMask;
barrier.oldLayout = *imageLayout;
barrier.newLayout = destLayout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(rendererData->currentCommandBuffer, srcStageFlags, dstStageFlags, 0, 0, NULL, 0, NULL, 1, &barrier);
*imageLayout = destLayout;
}
static VkResult VULKAN_AcquireNextSwapchainImage(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = ( VULKAN_RenderData * )renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result;
rendererData->currentImageAvailableSemaphore = VK_NULL_HANDLE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkAcquireNextImageKHR(rendererData->device, rendererData->swapchain, UINT64_MAX,
rendererData->imageAvailableSemaphores[rendererData->currentCommandBufferIndex], VK_NULL_HANDLE, &rendererData->currentSwapchainImageIndex);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_ERROR_SURFACE_LOST_KHR) {
result = VULKAN_CreateWindowSizeDependentResources(renderer);
return result;
} else if(result == VK_SUBOPTIMAL_KHR) {
// Suboptimal, but we can contiue
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
else if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAcquireNextImageKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
rendererData->currentImageAvailableSemaphore = rendererData->imageAvailableSemaphores[rendererData->currentCommandBufferIndex];
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return result;
}
static void VULKAN_BeginRenderPass(VULKAN_RenderData *rendererData, VkAttachmentLoadOp loadOp, VkClearColorValue *clearColor)
{
int width = rendererData->swapchainSize.width;
int height = rendererData->swapchainSize.height;
if (rendererData->textureRenderTarget) {
width = rendererData->textureRenderTarget->width;
height = rendererData->textureRenderTarget->height;
}
switch (loadOp) {
case VK_ATTACHMENT_LOAD_OP_CLEAR:
rendererData->currentRenderPass = rendererData->textureRenderTarget ?
rendererData->textureRenderTarget->mainRenderpasses[SDL_VULKAN_RENDERPASS_CLEAR] :
rendererData->renderPasses[SDL_VULKAN_RENDERPASS_CLEAR];
break;
case VK_ATTACHMENT_LOAD_OP_LOAD:
default:
rendererData->currentRenderPass = rendererData->textureRenderTarget ?
rendererData->textureRenderTarget->mainRenderpasses[SDL_VULKAN_RENDERPASS_LOAD] :
rendererData->renderPasses[SDL_VULKAN_RENDERPASS_LOAD];
break;
}
VkFramebuffer framebuffer = rendererData->textureRenderTarget ?
rendererData->textureRenderTarget->mainFramebuffer :
rendererData->framebuffers[rendererData->currentSwapchainImageIndex];
VkRenderPassBeginInfo renderPassBeginInfo = { 0 };
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = NULL;
renderPassBeginInfo.renderPass = rendererData->currentRenderPass;
renderPassBeginInfo.framebuffer = framebuffer;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = (clearColor == NULL) ? 0 : 1;
VkClearValue clearValue;
if (clearColor != NULL) {
clearValue.color = *clearColor;
renderPassBeginInfo.pClearValues = &clearValue;
}
vkCmdBeginRenderPass(rendererData->currentCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}
static void VULKAN_EnsureCommandBuffer(VULKAN_RenderData *rendererData)
{
if (rendererData->currentCommandBuffer == VK_NULL_HANDLE) {
rendererData->currentCommandBuffer = rendererData->commandBuffers[rendererData->currentCommandBufferIndex];
VULKAN_ResetCommandList(rendererData);
// Ensure the swapchain is in the correct layout
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->swapchainImageLayouts[rendererData->currentSwapchainImageIndex] == VK_IMAGE_LAYOUT_UNDEFINED) {
VULKAN_RecordPipelineImageBarrier(rendererData,
0,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
rendererData->swapchainImages[rendererData->currentSwapchainImageIndex],
&rendererData->swapchainImageLayouts[rendererData->currentSwapchainImageIndex]);
}
else if (rendererData->swapchainImageLayouts[rendererData->currentCommandBufferIndex] != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
rendererData->swapchainImages[rendererData->currentSwapchainImageIndex],
&rendererData->swapchainImageLayouts[rendererData->currentSwapchainImageIndex]);
}
}
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_ActivateCommandBuffer(SDL_Renderer *renderer, VkAttachmentLoadOp loadOp, VkClearColorValue *clearColor, VULKAN_DrawStateCache *stateCache)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_EnsureCommandBuffer(rendererData);
if (rendererData->currentRenderPass == VK_NULL_HANDLE || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
if (rendererData->currentRenderPass != VK_NULL_HANDLE) {
vkCmdEndRenderPass(rendererData->currentCommandBuffer);
rendererData->currentRenderPass = VK_NULL_HANDLE;
}
VULKAN_BeginRenderPass(rendererData, loadOp, clearColor);
}
// Bind cached VB now
if (stateCache->vertexBuffer != VK_NULL_HANDLE) {
VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(rendererData->currentCommandBuffer, 0, 1, &stateCache->vertexBuffer, &offset);
}
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static void VULKAN_WaitForGPU(VULKAN_RenderData *rendererData)
{
vkQueueWaitIdle(rendererData->graphicsQueue);
}
static void VULKAN_ResetCommandList(VULKAN_RenderData *rendererData)
{
vkResetCommandBuffer(rendererData->currentCommandBuffer, 0);
for (uint32_t i = 0; i < rendererData->numDescriptorPools[rendererData->currentCommandBufferIndex]; i++) {
vkResetDescriptorPool(rendererData->device, rendererData->descriptorPools[rendererData->currentCommandBufferIndex][i], 0);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkCommandBufferBeginInfo beginInfo = { 0 };
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0;
vkBeginCommandBuffer(rendererData->currentCommandBuffer, &beginInfo);
rendererData->currentPipelineState = NULL;
rendererData->currentVertexBuffer = 0;
2024-08-22 09:21:26 -07:00
rendererData->issueBatch = false;
rendererData->cliprectDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentDescriptorSetIndex = 0;
rendererData->currentDescriptorPoolIndex = 0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentConstantBufferOffset = -1;
rendererData->currentConstantBufferIndex = 0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Release any upload buffers that were inflight
for (int i = 0; i < rendererData->currentUploadBuffer[rendererData->currentCommandBufferIndex]; ++i) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyBuffer(rendererData, &rendererData->uploadBuffers[rendererData->currentCommandBufferIndex][i]);
}
rendererData->currentUploadBuffer[rendererData->currentCommandBufferIndex] = 0;
}
static VkResult VULKAN_IssueBatch(VULKAN_RenderData *rendererData)
{
VkResult result;
if (rendererData->currentCommandBuffer == VK_NULL_HANDLE) {
return VK_SUCCESS;
}
if (rendererData->currentRenderPass) {
vkCmdEndRenderPass(rendererData->currentCommandBuffer);
rendererData->currentRenderPass = VK_NULL_HANDLE;
}
rendererData->currentPipelineState = VK_NULL_HANDLE;
2024-08-22 09:21:26 -07:00
rendererData->viewportDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkEndCommandBuffer(rendererData->currentCommandBuffer);
VkSubmitInfo submitInfo = { 0 };
VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &rendererData->currentCommandBuffer;
if (rendererData->waitRenderSemaphoreCount > 0) {
Uint32 additionalSemaphoreCount = (rendererData->currentImageAvailableSemaphore != VK_NULL_HANDLE) ? 1 : 0;
submitInfo.waitSemaphoreCount = rendererData->waitRenderSemaphoreCount + additionalSemaphoreCount;
if (additionalSemaphoreCount > 0) {
rendererData->waitRenderSemaphores[rendererData->waitRenderSemaphoreCount] = rendererData->currentImageAvailableSemaphore;
rendererData->waitDestStageMasks[rendererData->waitRenderSemaphoreCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
}
submitInfo.pWaitSemaphores = rendererData->waitRenderSemaphores;
submitInfo.pWaitDstStageMask = rendererData->waitDestStageMasks;
rendererData->waitRenderSemaphoreCount = 0;
} else if (rendererData->currentImageAvailableSemaphore != VK_NULL_HANDLE) {
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &rendererData->currentImageAvailableSemaphore;
submitInfo.pWaitDstStageMask = &waitDestStageMask;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkQueueSubmit(rendererData->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
rendererData->currentImageAvailableSemaphore = VK_NULL_HANDLE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_WaitForGPU(rendererData);
VULKAN_ResetCommandList(rendererData);
return result;
}
static void VULKAN_DestroyRenderer(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData) {
if (rendererData->device != VK_NULL_HANDLE) {
vkDeviceWaitIdle(rendererData->device);
VULKAN_DestroyAll(renderer);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_free(rendererData);
}
}
static VkBlendFactor GetBlendFactor(SDL_BlendFactor factor)
{
switch (factor) {
case SDL_BLENDFACTOR_ZERO:
return VK_BLEND_FACTOR_ZERO;
case SDL_BLENDFACTOR_ONE:
return VK_BLEND_FACTOR_ONE;
case SDL_BLENDFACTOR_SRC_COLOR:
return VK_BLEND_FACTOR_SRC_COLOR;
case SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case SDL_BLENDFACTOR_SRC_ALPHA:
return VK_BLEND_FACTOR_SRC_ALPHA;
case SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
case SDL_BLENDFACTOR_DST_COLOR:
return VK_BLEND_FACTOR_DST_COLOR;
case SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
case SDL_BLENDFACTOR_DST_ALPHA:
return VK_BLEND_FACTOR_DST_ALPHA;
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
default:
return VK_BLEND_FACTOR_MAX_ENUM;
}
}
static VkBlendOp GetBlendOp(SDL_BlendOperation operation)
{
switch (operation) {
case SDL_BLENDOPERATION_ADD:
return VK_BLEND_OP_ADD;
case SDL_BLENDOPERATION_SUBTRACT:
return VK_BLEND_OP_SUBTRACT;
case SDL_BLENDOPERATION_REV_SUBTRACT:
return VK_BLEND_OP_REVERSE_SUBTRACT;
case SDL_BLENDOPERATION_MINIMUM:
return VK_BLEND_OP_MIN;
case SDL_BLENDOPERATION_MAXIMUM:
return VK_BLEND_OP_MAX;
default:
return VK_BLEND_OP_MAX_ENUM;
}
}
static VULKAN_PipelineState *VULKAN_CreatePipelineState(SDL_Renderer *renderer,
VULKAN_Shader shader, VkPipelineLayout pipelineLayout, VkDescriptorSetLayout descriptorSetLayout, SDL_BlendMode blendMode, VkPrimitiveTopology topology, VkFormat format)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_PipelineState *pipelineStates;
VkPipeline pipeline = VK_NULL_HANDLE;
VkResult result = VK_SUCCESS;
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo = { 0 };
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = { 0 };
VkVertexInputAttributeDescription attributeDescriptions[3];
VkVertexInputBindingDescription bindingDescriptions[1];
VkPipelineShaderStageCreateInfo shaderStageCreateInfo[2];
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = { 0 };
VkPipelineViewportStateCreateInfo viewportStateCreateInfo = { 0 };
VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = { 0 };
VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = { 0 };
VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = { 0 };
VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = { 0 };
VkGraphicsPipelineCreateInfo pipelineCreateInfo = { 0 };
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCreateInfo.flags = 0;
pipelineCreateInfo.pStages = shaderStageCreateInfo;
pipelineCreateInfo.pVertexInputState = &vertexInputCreateInfo;
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo;
pipelineCreateInfo.pViewportState = &viewportStateCreateInfo;
pipelineCreateInfo.pRasterizationState = &rasterizationStateCreateInfo;
pipelineCreateInfo.pMultisampleState = &multisampleStateCreateInfo;
pipelineCreateInfo.pDepthStencilState = &depthStencilStateCreateInfo;
pipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo;
pipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
// Shaders
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const char *name = "main";
for (uint32_t i = 0; i < 2; i++) {
SDL_memset(&shaderStageCreateInfo[i], 0, sizeof(shaderStageCreateInfo[i]));
shaderStageCreateInfo[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageCreateInfo[i].module = (i == 0) ? rendererData->vertexShaderModules[shader] : rendererData->fragmentShaderModules[shader];
shaderStageCreateInfo[i].stage = (i == 0) ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
shaderStageCreateInfo[i].pName = name;
}
pipelineCreateInfo.stageCount = 2;
pipelineCreateInfo.pStages = &shaderStageCreateInfo[0];
// Vertex input
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputCreateInfo.vertexAttributeDescriptionCount = 3;
vertexInputCreateInfo.pVertexAttributeDescriptions = &attributeDescriptions[0];
vertexInputCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputCreateInfo.pVertexBindingDescriptions = &bindingDescriptions[0];
attributeDescriptions[ 0 ].binding = 0;
attributeDescriptions[ 0 ].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[ 0 ].location = 0;
attributeDescriptions[ 0 ].offset = 0;
attributeDescriptions[ 1 ].binding = 0;
attributeDescriptions[ 1 ].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[ 1 ].location = 1;
attributeDescriptions[ 1 ].offset = 8;
attributeDescriptions[ 2 ].binding = 0;
attributeDescriptions[ 2 ].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attributeDescriptions[ 2 ].location = 2;
attributeDescriptions[ 2 ].offset = 16;
bindingDescriptions[ 0 ].binding = 0;
bindingDescriptions[ 0 ].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
bindingDescriptions[ 0 ].stride = 32;
// Input assembly
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
inputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssemblyStateCreateInfo.topology = ( VkPrimitiveTopology ) topology;
inputAssemblyStateCreateInfo.primitiveRestartEnable = VK_FALSE;
viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportStateCreateInfo.scissorCount = 1;
viewportStateCreateInfo.viewportCount = 1;
// Dynamic states
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
VkDynamicState dynamicStates[2] = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
dynamicStateCreateInfo.dynamicStateCount = SDL_arraysize(dynamicStates);
dynamicStateCreateInfo.pDynamicStates = dynamicStates;
// Rasterization state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
rasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
rasterizationStateCreateInfo.cullMode = VK_CULL_MODE_NONE;
rasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
rasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
rasterizationStateCreateInfo.depthBiasConstantFactor = 0.0f;
rasterizationStateCreateInfo.depthBiasClamp = 0.0f;
rasterizationStateCreateInfo.depthBiasSlopeFactor = 0.0f;
rasterizationStateCreateInfo.lineWidth = 1.0f;
// MSAA state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
multisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
VkSampleMask multiSampleMask = 0xFFFFFFFF;
multisampleStateCreateInfo.pSampleMask = &multiSampleMask;
multisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
// Depth Stencil
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
depthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
// Color blend
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkPipelineColorBlendAttachmentState colorBlendAttachment = { 0 };
colorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlendStateCreateInfo.attachmentCount = 1;
colorBlendStateCreateInfo.pAttachments = &colorBlendAttachment;
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = GetBlendFactor(SDL_GetBlendModeSrcColorFactor(blendMode));
colorBlendAttachment.srcAlphaBlendFactor = GetBlendFactor(SDL_GetBlendModeSrcAlphaFactor(blendMode));
colorBlendAttachment.colorBlendOp = GetBlendOp(SDL_GetBlendModeColorOperation(blendMode));
colorBlendAttachment.dstColorBlendFactor = GetBlendFactor(SDL_GetBlendModeDstColorFactor(blendMode));
colorBlendAttachment.dstAlphaBlendFactor = GetBlendFactor(SDL_GetBlendModeDstAlphaFactor(blendMode));
colorBlendAttachment.alphaBlendOp = GetBlendOp(SDL_GetBlendModeAlphaOperation(blendMode));
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
// Renderpass / layout
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
pipelineCreateInfo.renderPass = rendererData->currentRenderPass;
pipelineCreateInfo.subpass = 0;
pipelineCreateInfo.layout = pipelineLayout;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkCreateGraphicsPipelines(rendererData->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &pipeline);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateGraphicsPipelines(): %s\n", SDL_Vulkan_GetResultString(result));
return NULL;
}
pipelineStates = (VULKAN_PipelineState *)SDL_realloc(rendererData->pipelineStates, (rendererData->pipelineStateCount + 1) * sizeof(*pipelineStates));
pipelineStates[rendererData->pipelineStateCount].shader = shader;
pipelineStates[rendererData->pipelineStateCount].blendMode = blendMode;
pipelineStates[rendererData->pipelineStateCount].topology = topology;
pipelineStates[rendererData->pipelineStateCount].format = format;
pipelineStates[rendererData->pipelineStateCount].pipeline = pipeline;
pipelineStates[rendererData->pipelineStateCount].descriptorSetLayout = descriptorSetLayout;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
pipelineStates[rendererData->pipelineStateCount].pipelineLayout = pipelineCreateInfo.layout;
rendererData->pipelineStates = pipelineStates;
++rendererData->pipelineStateCount;
return &pipelineStates[rendererData->pipelineStateCount - 1];
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_FindMemoryTypeIndex(VULKAN_RenderData *rendererData, uint32_t typeBits, VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags desiredFlags, uint32_t *memoryTypeIndexOut)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
uint32_t memoryTypeIndex = 0;
2024-08-22 09:21:26 -07:00
bool foundExactMatch = false;
// Desired flags must be a superset of required flags.
desiredFlags |= requiredFlags;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (memoryTypeIndex = 0; memoryTypeIndex < rendererData->physicalDeviceMemoryProperties.memoryTypeCount; memoryTypeIndex++) {
if (typeBits & (1 << memoryTypeIndex)) {
if (rendererData->physicalDeviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags == desiredFlags) {
2024-08-22 09:21:26 -07:00
foundExactMatch = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
}
}
}
if (!foundExactMatch) {
for (memoryTypeIndex = 0; memoryTypeIndex < rendererData->physicalDeviceMemoryProperties.memoryTypeCount; memoryTypeIndex++) {
if (typeBits & (1 << memoryTypeIndex)) {
if ((rendererData->physicalDeviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & requiredFlags) == requiredFlags) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
}
}
}
}
if (memoryTypeIndex >= rendererData->physicalDeviceMemoryProperties.memoryTypeCount) {
2024-02-28 19:11:33 -08:00
SDL_SetError("[Vulkan] Unable to find memory type for allocation");
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
*memoryTypeIndexOut = memoryTypeIndex;
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static VkResult VULKAN_CreateVertexBuffer(VULKAN_RenderData *rendererData, size_t vbidx, size_t size)
{
VkResult result;
VULKAN_DestroyBuffer(rendererData, &rendererData->vertexBuffers[vbidx]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = VULKAN_AllocateBuffer(rendererData, size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
&rendererData->vertexBuffers[vbidx]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateBuffer(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
return result;
}
static int VULKAN_LoadGlobalFunctions(VULKAN_RenderData *rendererData)
{
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name) \
name = (PFN_##name)rendererData->vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
if (!name) { \
SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
"vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
return -1; \
}
#define VULKAN_INSTANCE_FUNCTION(name)
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name)
#define VULKAN_OPTIONAL_DEVICE_FUNCTION(name)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_DEVICE_FUNCTION
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static int VULKAN_LoadInstanceFunctions(VULKAN_RenderData *rendererData)
{
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name) \
name = (PFN_##name)rendererData->vkGetInstanceProcAddr(rendererData->instance, #name); \
if (!name) { \
SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
"vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
return -1; \
}
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name) \
name = (PFN_##name)rendererData->vkGetInstanceProcAddr(rendererData->instance, #name);
#define VULKAN_OPTIONAL_DEVICE_FUNCTION(name)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_DEVICE_FUNCTION
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static int VULKAN_LoadDeviceFunctions(VULKAN_RenderData *rendererData)
{
#define VULKAN_DEVICE_FUNCTION(name) \
name = (PFN_##name)vkGetDeviceProcAddr(rendererData->device, #name); \
if (!name) { \
SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
"vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
return -1; \
}
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_OPTIONAL_DEVICE_FUNCTION(name) \
name = (PFN_##name)vkGetDeviceProcAddr(rendererData->device, #name);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
#define VULKAN_INSTANCE_FUNCTION(name)
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_FUNCTIONS()
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_INSTANCE_FUNCTION
#undef VULKAN_OPTIONAL_DEVICE_FUNCTION
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
{
uint32_t physicalDeviceCount = 0;
VkPhysicalDevice *physicalDevices;
VkQueueFamilyProperties *queueFamiliesProperties = NULL;
uint32_t queueFamiliesPropertiesAllocatedSize = 0;
VkExtensionProperties *deviceExtensions = NULL;
uint32_t deviceExtensionsAllocatedSize = 0;
uint32_t physicalDeviceIndex;
VkResult result;
result = vkEnumeratePhysicalDevices(rendererData->instance, &physicalDeviceCount, NULL);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumeratePhysicalDevices(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
if (physicalDeviceCount == 0) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumeratePhysicalDevices(): no physical devices\n");
return VK_ERROR_UNKNOWN;
}
physicalDevices = (VkPhysicalDevice *)SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
result = vkEnumeratePhysicalDevices(rendererData->instance, &physicalDeviceCount, physicalDevices);
if (result != VK_SUCCESS) {
SDL_free(physicalDevices);
SDL_LogError(SDL_LOG_CATEGORY_RENDER,"vkEnumeratePhysicalDevices(): %s\n",SDL_Vulkan_GetResultString(result));
return result;
}
rendererData->physicalDevice = NULL;
for (physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) {
uint32_t queueFamiliesCount = 0;
uint32_t queueFamilyIndex;
uint32_t deviceExtensionCount = 0;
2024-08-22 09:21:26 -07:00
bool hasSwapchainExtension = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uint32_t i;
VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
vkGetPhysicalDeviceProperties(physicalDevice, &rendererData->physicalDeviceProperties);
if (VK_VERSION_MAJOR(rendererData->physicalDeviceProperties.apiVersion) < 1) {
continue;
}
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &rendererData->physicalDeviceMemoryProperties);
vkGetPhysicalDeviceFeatures(physicalDevice, &rendererData->physicalDeviceFeatures);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL);
if (queueFamiliesCount == 0) {
continue;
}
if (queueFamiliesPropertiesAllocatedSize < queueFamiliesCount) {
SDL_free(queueFamiliesProperties);
queueFamiliesPropertiesAllocatedSize = queueFamiliesCount;
queueFamiliesProperties = (VkQueueFamilyProperties *)SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize);
if (!queueFamiliesProperties) {
SDL_free(physicalDevices);
SDL_free(deviceExtensions);
return VK_ERROR_UNKNOWN;
}
}
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, queueFamiliesProperties);
rendererData->graphicsQueueFamilyIndex = queueFamiliesCount;
rendererData->presentQueueFamilyIndex = queueFamiliesCount;
for (queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount; queueFamilyIndex++) {
VkBool32 supported = 0;
if (queueFamiliesProperties[queueFamilyIndex].queueCount == 0) {
continue;
}
if (queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
rendererData->graphicsQueueFamilyIndex = queueFamilyIndex;
}
result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, rendererData->surface, &supported);
if (result != VK_SUCCESS) {
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return VK_ERROR_UNKNOWN;
}
if (supported) {
rendererData->presentQueueFamilyIndex = queueFamilyIndex;
if (queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
break; // use this queue because it can present and do graphics
}
}
}
if (rendererData->graphicsQueueFamilyIndex == queueFamiliesCount) { // no good queues found
continue;
}
if (rendererData->presentQueueFamilyIndex == queueFamiliesCount) { // no good queues found
continue;
}
result = vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL);
if (result != VK_SUCCESS) {
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties(): %s\n", SDL_Vulkan_GetResultString(result));
return VK_ERROR_UNKNOWN;
}
if (deviceExtensionCount == 0) {
continue;
}
if (deviceExtensionsAllocatedSize < deviceExtensionCount) {
SDL_free(deviceExtensions);
deviceExtensionsAllocatedSize = deviceExtensionCount;
deviceExtensions = (VkExtensionProperties *)SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!deviceExtensions) {
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
return VK_ERROR_UNKNOWN;
}
}
result = vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, deviceExtensions);
if (result != VK_SUCCESS) {
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
for (i = 0; i < deviceExtensionCount; i++) {
if (SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
2024-08-22 09:21:26 -07:00
hasSwapchainExtension = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
}
}
if (!hasSwapchainExtension) {
continue;
}
rendererData->physicalDevice = physicalDevice;
break;
}
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
if (!rendererData->physicalDevice) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Vulkan: no viable physical devices found");
return VK_ERROR_UNKNOWN;
}
return VK_SUCCESS;
}
static VkResult VULKAN_GetSurfaceFormats(VULKAN_RenderData *rendererData)
{
VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(rendererData->physicalDevice,
rendererData->surface,
&rendererData->surfaceFormatsCount,
NULL);
if (result != VK_SUCCESS) {
rendererData->surfaceFormatsCount = 0;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
if (rendererData->surfaceFormatsCount > rendererData->surfaceFormatsAllocatedCount) {
rendererData->surfaceFormatsAllocatedCount = rendererData->surfaceFormatsCount;
SDL_free(rendererData->surfaceFormats);
rendererData->surfaceFormats = (VkSurfaceFormatKHR *)SDL_malloc(sizeof(VkSurfaceFormatKHR) * rendererData->surfaceFormatsAllocatedCount);
}
result = vkGetPhysicalDeviceSurfaceFormatsKHR(rendererData->physicalDevice,
rendererData->surface,
&rendererData->surfaceFormatsCount,
rendererData->surfaceFormats);
if (result != VK_SUCCESS) {
rendererData->surfaceFormatsCount = 0;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return VK_SUCCESS;
}
static VkSemaphore VULKAN_CreateSemaphore(VULKAN_RenderData *rendererData)
{
VkResult result;
VkSemaphore semaphore = VK_NULL_HANDLE;
VkSemaphoreCreateInfo semaphoreCreateInfo = { 0 };
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
result = vkCreateSemaphore(rendererData->device, &semaphoreCreateInfo, NULL, &semaphore);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSemaphore(): %s\n", SDL_Vulkan_GetResultString(result));
return VK_NULL_HANDLE;
}
return semaphore;
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_DeviceExtensionsFound(VULKAN_RenderData *rendererData, int extensionsToCheck, const char* const* extNames)
{
uint32_t extensionCount;
2024-08-22 09:21:26 -07:00
bool foundExtensions = true;
VkResult result = vkEnumerateDeviceExtensionProperties(rendererData->physicalDevice, NULL, &extensionCount, NULL);
if (result != VK_SUCCESS ) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties(): %s.\n", SDL_Vulkan_GetResultString(result));
2024-08-22 09:21:26 -07:00
return false;
}
if (extensionCount > 0 ) {
VkExtensionProperties *extensionProperties = (VkExtensionProperties *)SDL_calloc(sizeof(VkExtensionProperties), extensionCount);
result = vkEnumerateDeviceExtensionProperties(rendererData->physicalDevice, NULL, &extensionCount, extensionProperties);
if (result != VK_SUCCESS ) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties): %s.\n", SDL_Vulkan_GetResultString(result));
SDL_free(extensionProperties);
2024-08-22 09:21:26 -07:00
return false;
}
for (int ext = 0; ext < extensionsToCheck && foundExtensions; ext++) {
2024-08-22 09:21:26 -07:00
bool foundExtension = false;
for (uint32_t i = 0; i < extensionCount; i++) {
if (SDL_strcmp(extensionProperties[i].extensionName, extNames[ext]) == 0) {
2024-08-22 09:21:26 -07:00
foundExtension = true;
break;
}
}
foundExtensions &= foundExtension;
}
SDL_free(extensionProperties);
}
return foundExtensions;
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_InstanceExtensionFound(VULKAN_RenderData *rendererData, const char *extName)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
uint32_t extensionCount;
VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
if (result != VK_SUCCESS ) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateInstanceExtensionProperties( NULL, ... ): %s.\n", SDL_Vulkan_GetResultString(result));
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (extensionCount > 0 ) {
VkExtensionProperties *extensionProperties = (VkExtensionProperties *)SDL_calloc(extensionCount, sizeof(VkExtensionProperties));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensionProperties);
if (result != VK_SUCCESS ) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateInstanceExtensionProperties( NULL, ... ): %s.\n", SDL_Vulkan_GetResultString(result));
SDL_free(extensionProperties);
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
for (uint32_t i = 0; i< extensionCount; i++) {
if (SDL_strcmp(extensionProperties[i].extensionName, extName) == 0) {
SDL_free(extensionProperties);
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
SDL_free(extensionProperties);
}
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_ValidationLayersFound(void)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
uint32_t instanceLayerCount = 0;
uint32_t i;
2024-08-22 09:21:26 -07:00
bool foundValidation = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkEnumerateInstanceLayerProperties(&instanceLayerCount, NULL);
if (instanceLayerCount > 0) {
VkLayerProperties *instanceLayers = (VkLayerProperties *)SDL_calloc(instanceLayerCount, sizeof(VkLayerProperties));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayers);
for (i = 0; i < instanceLayerCount; i++) {
if (!SDL_strcmp(SDL_VULKAN_VALIDATION_LAYER_NAME, instanceLayers[i].layerName)) {
2024-08-22 09:21:26 -07:00
foundValidation = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
}
}
SDL_free(instanceLayers);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return foundValidation;
}
// Create resources that depend on the device.
static VkResult VULKAN_CreateDeviceResources(SDL_Renderer *renderer, SDL_PropertiesID create_props)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
static const char *const deviceExtensionNames[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
/* VK_KHR_sampler_ycbcr_conversion + dependent extensions.
Note VULKAN_DeviceExtensionsFound() call below, if these get moved in this
array, update that check too.
*/
VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
VK_KHR_MAINTENANCE1_EXTENSION_NAME,
VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
};
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_VideoDevice *device = SDL_GetVideoDevice();
VkResult result = VK_SUCCESS;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
2024-08-22 09:21:26 -07:00
bool createDebug = SDL_GetHintBoolean(SDL_HINT_RENDER_VULKAN_DEBUG, false);
const char *validationLayerName[] = { SDL_VULKAN_VALIDATION_LAYER_NAME };
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (SDL_Vulkan_LoadLibrary(NULL) < 0) {
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "SDL_Vulkan_LoadLibrary failed." );
return VK_ERROR_UNKNOWN;
}
vkGetInstanceProcAddr = device ? (PFN_vkGetInstanceProcAddr)device->vulkan_config.vkGetInstanceProcAddr : NULL;
if(!vkGetInstanceProcAddr) {
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "vkGetInstanceProcAddr is NULL" );
return VK_ERROR_UNKNOWN;
}
// Load global Vulkan functions
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->vkGetInstanceProcAddr = vkGetInstanceProcAddr;
if (VULKAN_LoadGlobalFunctions(rendererData) != 0) {
return VK_ERROR_UNKNOWN;
}
// Check for colorspace extension
rendererData->supportsEXTSwapchainColorspace = VK_FALSE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (renderer->output_colorspace == SDL_COLORSPACE_SRGB_LINEAR ||
renderer->output_colorspace == SDL_COLORSPACE_HDR10) {
rendererData->supportsEXTSwapchainColorspace = VULKAN_InstanceExtensionFound(rendererData, VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
if (!rendererData->supportsEXTSwapchainColorspace) {
SDL_SetError("[Vulkan] Using HDR output but %s not supported", VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
return VK_ERROR_UNKNOWN;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
// Check for VK_KHR_get_physical_device_properties2
rendererData->supportsKHRGetPhysicalDeviceProperties2 = VULKAN_InstanceExtensionFound(rendererData, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
// Create VkInstance
rendererData->instance = (VkInstance)SDL_GetPointerProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_INSTANCE_POINTER, NULL);
if (rendererData->instance) {
2024-08-22 09:21:26 -07:00
rendererData->instance_external = true;
} else {
VkInstanceCreateInfo instanceCreateInfo = { 0 };
VkApplicationInfo appInfo = { 0 };
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.apiVersion = VK_API_VERSION_1_0;
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &appInfo;
char const *const *instanceExtensions = SDL_Vulkan_GetInstanceExtensions(&instanceCreateInfo.enabledExtensionCount);
const char **instanceExtensionsCopy = (const char **)SDL_calloc(instanceCreateInfo.enabledExtensionCount + 2, sizeof(const char *));
for (uint32_t i = 0; i < instanceCreateInfo.enabledExtensionCount; i++) {
instanceExtensionsCopy[i] = instanceExtensions[i];
}
if (rendererData->supportsEXTSwapchainColorspace) {
instanceExtensionsCopy[instanceCreateInfo.enabledExtensionCount] = VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME;
instanceCreateInfo.enabledExtensionCount++;
}
if (rendererData->supportsKHRGetPhysicalDeviceProperties2) {
instanceExtensionsCopy[instanceCreateInfo.enabledExtensionCount] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
instanceCreateInfo.enabledExtensionCount++;
}
instanceCreateInfo.ppEnabledExtensionNames = (const char *const *)instanceExtensionsCopy;
if (createDebug && VULKAN_ValidationLayersFound()) {
instanceCreateInfo.ppEnabledLayerNames = validationLayerName;
instanceCreateInfo.enabledLayerCount = 1;
}
result = vkCreateInstance(&instanceCreateInfo, NULL, &rendererData->instance);
SDL_free((void *)instanceExtensionsCopy);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateInstance(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// Load instance Vulkan functions
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (VULKAN_LoadInstanceFunctions(rendererData) != 0) {
VULKAN_DestroyAll(renderer);
return VK_ERROR_UNKNOWN;
}
// Create Vulkan surface
rendererData->surface = (VkSurfaceKHR)SDL_GetNumberProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_SURFACE_NUMBER, 0);
if (rendererData->surface) {
2024-08-22 09:21:26 -07:00
rendererData->surface_external = true;
} else {
if (!device->Vulkan_CreateSurface || (device->Vulkan_CreateSurface(device, renderer->window, rendererData->instance, NULL, &rendererData->surface) < 0)) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Vulkan_CreateSurface() failed.\n");
return VK_ERROR_UNKNOWN;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// Choose Vulkan physical device
rendererData->physicalDevice = (VkPhysicalDevice)SDL_GetPointerProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_PHYSICAL_DEVICE_POINTER, NULL);
if (rendererData->physicalDevice) {
vkGetPhysicalDeviceMemoryProperties(rendererData->physicalDevice, &rendererData->physicalDeviceMemoryProperties);
vkGetPhysicalDeviceFeatures(rendererData->physicalDevice, &rendererData->physicalDeviceFeatures);
} else {
if (VULKAN_FindPhysicalDevice(rendererData) != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
return VK_ERROR_UNKNOWN;
}
}
if (SDL_HasProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER)) {
rendererData->graphicsQueueFamilyIndex = (uint32_t)SDL_GetNumberProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, 0);
}
if (SDL_HasProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_PRESENT_QUEUE_FAMILY_INDEX_NUMBER)) {
rendererData->presentQueueFamilyIndex = (uint32_t)SDL_GetNumberProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_PRESENT_QUEUE_FAMILY_INDEX_NUMBER, 0);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->supportsKHRGetPhysicalDeviceProperties2 &&
VULKAN_DeviceExtensionsFound(rendererData, 4, &deviceExtensionNames[1])) {
2024-08-22 09:21:26 -07:00
rendererData->supportsKHRSamplerYCbCrConversion = true;
}
// Create Vulkan device
rendererData->device = (VkDevice)SDL_GetPointerProperty(create_props, SDL_PROP_RENDERER_CREATE_VULKAN_DEVICE_POINTER, NULL);
if (rendererData->device) {
2024-08-22 09:21:26 -07:00
rendererData->device_external = true;
} else {
VkPhysicalDeviceSamplerYcbcrConversionFeatures deviceSamplerYcbcrConversionFeatures = { 0 };
VkDeviceQueueCreateInfo deviceQueueCreateInfo[2] = { { 0 }, { 0 } };
static const float queuePriority[] = { 1.0f };
VkDeviceCreateInfo deviceCreateInfo = { 0 };
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.queueCreateInfoCount = 0;
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
deviceCreateInfo.pEnabledFeatures = NULL;
deviceCreateInfo.enabledExtensionCount = (rendererData->supportsKHRSamplerYCbCrConversion) ? 5 : 1;
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;
deviceQueueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo[0].queueFamilyIndex = rendererData->graphicsQueueFamilyIndex;
deviceQueueCreateInfo[0].queueCount = 1;
deviceQueueCreateInfo[0].pQueuePriorities = queuePriority;
++deviceCreateInfo.queueCreateInfoCount;
if (rendererData->presentQueueFamilyIndex != rendererData->graphicsQueueFamilyIndex) {
deviceQueueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo[1].queueFamilyIndex = rendererData->presentQueueFamilyIndex;
deviceQueueCreateInfo[1].queueCount = 1;
deviceQueueCreateInfo[1].pQueuePriorities = queuePriority;
++deviceCreateInfo.queueCreateInfoCount;
}
if (rendererData->supportsKHRSamplerYCbCrConversion) {
deviceSamplerYcbcrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
deviceSamplerYcbcrConversionFeatures.samplerYcbcrConversion = VK_TRUE;
deviceSamplerYcbcrConversionFeatures.pNext = (void *)deviceCreateInfo.pNext;
deviceCreateInfo.pNext = &deviceSamplerYcbcrConversionFeatures;
}
result = vkCreateDevice(rendererData->physicalDevice, &deviceCreateInfo, NULL, &rendererData->device);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateDevice(): %s\n", SDL_Vulkan_GetResultString(result));
VULKAN_DestroyAll(renderer);
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (VULKAN_LoadDeviceFunctions(rendererData) != 0) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyAll(renderer);
return VK_ERROR_UNKNOWN;
}
// Get graphics/present queues
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkGetDeviceQueue(rendererData->device, rendererData->graphicsQueueFamilyIndex, 0, &rendererData->graphicsQueue);
if (rendererData->graphicsQueueFamilyIndex != rendererData->presentQueueFamilyIndex) {
vkGetDeviceQueue(rendererData->device, rendererData->presentQueueFamilyIndex, 0, &rendererData->presentQueue);
} else {
rendererData->presentQueue = rendererData->graphicsQueue;
}
// Create command pool/command buffers
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkCommandPoolCreateInfo commandPoolCreateInfo = { 0 };
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
commandPoolCreateInfo.queueFamilyIndex = rendererData->graphicsQueueFamilyIndex;
result = vkCreateCommandPool(rendererData->device, &commandPoolCreateInfo, NULL, &rendererData->commandPool);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateCommandPool(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (VULKAN_GetSurfaceFormats(rendererData) != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
return result;
}
// Create shaders / layouts
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < NUM_SHADERS; i++) {
VULKAN_Shader shader = (VULKAN_Shader)i;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkShaderModuleCreateInfo shaderModuleCreateInfo = { 0 };
shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
VULKAN_GetVertexShader(shader, &shaderModuleCreateInfo.pCode, &shaderModuleCreateInfo.codeSize);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkCreateShaderModule(rendererData->device, &shaderModuleCreateInfo, NULL, &rendererData->vertexShaderModules[i]);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateShaderModule(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
VULKAN_GetPixelShader(shader, &shaderModuleCreateInfo.pCode, &shaderModuleCreateInfo.codeSize);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkCreateShaderModule(rendererData->device, &shaderModuleCreateInfo, NULL, &rendererData->fragmentShaderModules[i]);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateShaderModule(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Descriptor set layout / pipeline layout
result = VULKAN_CreateDescriptorSetAndPipelineLayout(rendererData, VK_NULL_HANDLE, &rendererData->descriptorSetLayout, &rendererData->pipelineLayout);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_CreateDescriptorSetAndPipelineLayout(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// Create default vertex buffers
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < SDL_VULKAN_NUM_VERTEX_BUFFERS; ++i) {
VULKAN_CreateVertexBuffer(rendererData, i, SDL_VULKAN_VERTEX_BUFFER_DEFAULT_SIZE);
}
// Create samplers
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
static struct
{
VkFilter filter;
VkSamplerAddressMode address;
} samplerParams[] = {
{ VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
{ VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT },
{ VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
{ VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT },
};
SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_VULKAN_NUM_SAMPLERS);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkSamplerCreateInfo samplerCreateInfo = { 0 };
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerCreateInfo.mipLodBias = 0.0f;
samplerCreateInfo.anisotropyEnable = VK_FALSE;
samplerCreateInfo.maxAnisotropy = 1.0f;
samplerCreateInfo.minLod = 0.0f;
samplerCreateInfo.maxLod = 1000.0f;
for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
samplerCreateInfo.magFilter = samplerParams[i].filter;
samplerCreateInfo.minFilter = samplerParams[i].filter;
samplerCreateInfo.addressModeU = samplerParams[i].address;
samplerCreateInfo.addressModeV = samplerParams[i].address;
result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &rendererData->samplers[i]);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSampler(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_VULKAN_INSTANCE_POINTER, rendererData->instance);
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_SURFACE_NUMBER, (Sint64)rendererData->surface);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_VULKAN_PHYSICAL_DEVICE_POINTER, rendererData->physicalDevice);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_VULKAN_DEVICE_POINTER, rendererData->device);
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, rendererData->graphicsQueueFamilyIndex);
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_PRESENT_QUEUE_FAMILY_INDEX_NUMBER, rendererData->presentQueueFamilyIndex);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return VK_SUCCESS;
}
static VkResult VULKAN_CreateFramebuffersAndRenderPasses(SDL_Renderer *renderer, int w, int h,
VkFormat format, int imageViewCount, VkImageView *imageViews, VkFramebuffer *framebuffers, VkRenderPass renderPasses[SDL_VULKAN_NUM_RENDERPASSES])
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *) renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result;
VkAttachmentDescription attachmentDescription = { 0 };
attachmentDescription.format = format;
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
attachmentDescription.flags = 0;
VkAttachmentReference colorAttachmentReference = { 0 };
colorAttachmentReference.attachment = 0;
colorAttachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpassDescription = { 0 };
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpassDescription.flags = 0;
subpassDescription.inputAttachmentCount = 0;
subpassDescription.pInputAttachments = NULL;
subpassDescription.colorAttachmentCount = 1;
subpassDescription.pColorAttachments = &colorAttachmentReference;
subpassDescription.pResolveAttachments = NULL;
subpassDescription.pDepthStencilAttachment = NULL;
subpassDescription.preserveAttachmentCount = 0;
subpassDescription.pPreserveAttachments = NULL;
VkSubpassDependency subPassDependency = { 0 };
subPassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
subPassDependency.dstSubpass = 0;
subPassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subPassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subPassDependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subPassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
subPassDependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderPassCreateInfo = { 0 };
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.flags = 0;
renderPassCreateInfo.attachmentCount = 1;
renderPassCreateInfo.pAttachments = &attachmentDescription;
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subpassDescription;
renderPassCreateInfo.dependencyCount = 1;
renderPassCreateInfo.pDependencies = &subPassDependency;
result = vkCreateRenderPass(rendererData->device, &renderPassCreateInfo, NULL, &renderPasses[SDL_VULKAN_RENDERPASS_LOAD]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateRenderPass(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
result = vkCreateRenderPass(rendererData->device, &renderPassCreateInfo, NULL, &renderPasses[SDL_VULKAN_RENDERPASS_CLEAR]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateRenderPass(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
VkFramebufferCreateInfo framebufferCreateInfo = { 0 };
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferCreateInfo.pNext = NULL;
framebufferCreateInfo.renderPass = rendererData->renderPasses[SDL_VULKAN_RENDERPASS_LOAD];
framebufferCreateInfo.attachmentCount = 1;
framebufferCreateInfo.width = w;
framebufferCreateInfo.height = h;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
framebufferCreateInfo.layers = 1;
for (int i = 0; i < imageViewCount; i++) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
framebufferCreateInfo.pAttachments = &imageViews[i];
result = vkCreateFramebuffer(rendererData->device, &framebufferCreateInfo, NULL, &framebuffers[i]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateFramebuffer(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
}
return result;
}
static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(rendererData->physicalDevice, rendererData->surface, &rendererData->surfaceCapabilities);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// pick an image count
rendererData->swapchainDesiredImageCount = rendererData->surfaceCapabilities.minImageCount + SDL_VULKAN_FRAME_QUEUE_DEPTH;
if ((rendererData->swapchainDesiredImageCount > rendererData->surfaceCapabilities.maxImageCount) &&
(rendererData->surfaceCapabilities.maxImageCount > 0)) {
rendererData->swapchainDesiredImageCount = rendererData->surfaceCapabilities.maxImageCount;
}
VkFormat desiredFormat = VK_FORMAT_B8G8R8A8_UNORM;
VkColorSpaceKHR desiredColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
if (renderer->output_colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
desiredFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
desiredColorSpace = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT;
}
else if (renderer->output_colorspace == SDL_COLORSPACE_HDR10) {
desiredFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
desiredColorSpace = VK_COLOR_SPACE_HDR10_ST2084_EXT;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if ((rendererData->surfaceFormatsCount == 1) &&
(rendererData->surfaceFormats[0].format == VK_FORMAT_UNDEFINED)) {
// aren't any preferred formats, so we pick
rendererData->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
rendererData->surfaceFormat.format = desiredFormat;
} else {
rendererData->surfaceFormat = rendererData->surfaceFormats[0];
rendererData->surfaceFormat.colorSpace = rendererData->surfaceFormats[0].colorSpace;
for (uint32_t i = 0; i < rendererData->surfaceFormatsCount; i++) {
if (rendererData->surfaceFormats[i].format == desiredFormat &&
rendererData->surfaceFormats[i].colorSpace == desiredColorSpace) {
rendererData->surfaceFormat.colorSpace = rendererData->surfaceFormats[i].colorSpace;
rendererData->surfaceFormat = rendererData->surfaceFormats[i];
break;
}
}
}
rendererData->swapchainSize.width = SDL_clamp((uint32_t)w,
rendererData->surfaceCapabilities.minImageExtent.width,
rendererData->surfaceCapabilities.maxImageExtent.width);
rendererData->swapchainSize.height = SDL_clamp((uint32_t)h,
rendererData->surfaceCapabilities.minImageExtent.height,
rendererData->surfaceCapabilities.maxImageExtent.height);
if (rendererData->swapchainSize.width == 0 && rendererData->swapchainSize.height == 0) {
// Don't recreate the swapchain if size is (0,0), just fail and continue attempting creation
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return VK_ERROR_OUT_OF_DATE_KHR;
}
// Choose a present mode. If vsync is requested, then use VK_PRESENT_MODE_FIFO_KHR which is guaranteed to be supported
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
if (rendererData->vsync <= 0) {
uint32_t presentModeCount = 0;
result = vkGetPhysicalDeviceSurfacePresentModesKHR(rendererData->physicalDevice, rendererData->surface, &presentModeCount, NULL);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfacePresentModesKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
if (presentModeCount > 0) {
VkPresentModeKHR *presentModes = (VkPresentModeKHR *)SDL_calloc(presentModeCount, sizeof(VkPresentModeKHR));
result = vkGetPhysicalDeviceSurfacePresentModesKHR(rendererData->physicalDevice, rendererData->surface, &presentModeCount, presentModes);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfacePresentModesKHR(): %s\n", SDL_Vulkan_GetResultString(result));
SDL_free(presentModes);
return result;
}
if (rendererData->vsync == 0) {
/* If vsync is not requested, in favor these options in order:
VK_PRESENT_MODE_IMMEDIATE_KHR - no v-sync with tearing
VK_PRESENT_MODE_MAILBOX_KHR - no v-sync without tearing
VK_PRESENT_MODE_FIFO_RELAXED_KHR - no v-sync, may tear */
for (uint32_t i = 0; i < presentModeCount; i++) {
if (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
break;
}
else if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
}
else if ((presentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
(presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)) {
presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
}
}
} else if (rendererData->vsync == -1) {
for (uint32_t i = 0; i < presentModeCount; i++) {
if (presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
break;
}
}
}
SDL_free(presentModes);
}
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkSwapchainCreateInfoKHR swapchainCreateInfo = { 0 };
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCreateInfo.surface = rendererData->surface;
swapchainCreateInfo.minImageCount = rendererData->swapchainDesiredImageCount;
swapchainCreateInfo.imageFormat = rendererData->surfaceFormat.format;
swapchainCreateInfo.imageColorSpace = rendererData->surfaceFormat.colorSpace;
swapchainCreateInfo.imageExtent = rendererData->swapchainSize;
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapchainCreateInfo.preTransform = rendererData->surfaceCapabilities.currentTransform;
swapchainCreateInfo.compositeAlpha = (renderer->window->flags & SDL_WINDOW_TRANSPARENT) ? 0 : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swapchainCreateInfo.presentMode = presentMode;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
swapchainCreateInfo.clipped = VK_TRUE;
swapchainCreateInfo.oldSwapchain = rendererData->swapchain;
result = vkCreateSwapchainKHR(rendererData->device, &swapchainCreateInfo, NULL, &rendererData->swapchain);
if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(rendererData->device, swapchainCreateInfo.oldSwapchain, NULL);
}
if (result != VK_SUCCESS) {
rendererData->swapchain = VK_NULL_HANDLE;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSwapchainKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
SDL_free(rendererData->swapchainImages);
rendererData->swapchainImages = NULL;
result = vkGetSwapchainImagesKHR(rendererData->device, rendererData->swapchain, &rendererData->swapchainImageCount, NULL);
if (result != VK_SUCCESS) {
rendererData->swapchainImageCount = 0;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetSwapchainImagesKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
rendererData->swapchainImages = (VkImage *)SDL_malloc(sizeof(VkImage) * rendererData->swapchainImageCount);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkGetSwapchainImagesKHR(rendererData->device,
rendererData->swapchain,
&rendererData->swapchainImageCount,
rendererData->swapchainImages);
if (result != VK_SUCCESS) {
SDL_free(rendererData->swapchainImages);
rendererData->swapchainImages = NULL;
rendererData->swapchainImageCount = 0;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetSwapchainImagesKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
// Create VkImageView's for swapchain images
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VkImageViewCreateInfo imageViewCreateInfo = { 0 };
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.flags = 0;
imageViewCreateInfo.format = rendererData->surfaceFormat.format;
imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
if (rendererData->swapchainImageViews) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
vkDestroyImageView(rendererData->device, rendererData->swapchainImageViews[i], NULL);
}
SDL_free(rendererData->swapchainImageViews);
}
rendererData->swapchainImageViews = (VkImageView *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkImageView));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_free(rendererData->swapchainImageLayouts);
rendererData->swapchainImageLayouts = (VkImageLayout *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkImageLayout));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
imageViewCreateInfo.image = rendererData->swapchainImages[i];
result = vkCreateImageView(rendererData->device, &imageViewCreateInfo, NULL, &rendererData->swapchainImageViews[i]);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateImageView(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
rendererData->swapchainImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
VkCommandBufferAllocateInfo commandBufferAllocateInfo = { 0 };
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.commandPool = rendererData->commandPool;
commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocateInfo.commandBufferCount = rendererData->swapchainImageCount;
if (rendererData->commandBuffers != NULL) {
vkResetCommandPool(rendererData->device, rendererData->commandPool, 0);
SDL_free(rendererData->commandBuffers);
rendererData->currentCommandBuffer = VK_NULL_HANDLE;
rendererData->currentCommandBufferIndex = 0;
}
rendererData->commandBuffers = (VkCommandBuffer *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkCommandBuffer));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkAllocateCommandBuffers(rendererData->device, &commandBufferAllocateInfo, rendererData->commandBuffers);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAllocateCommandBuffers(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
// Create fences
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->fences) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->fences[i] != VK_NULL_HANDLE) {
vkDestroyFence(rendererData->device, rendererData->fences[i], NULL);
}
}
SDL_free(rendererData->fences);
}
rendererData->fences = (VkFence *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkFence));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
VkFenceCreateInfo fenceCreateInfo = { 0 };
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
result = vkCreateFence(rendererData->device, &fenceCreateInfo, NULL, &rendererData->fences[i]);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateFence(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
}
// Create renderpasses and framebuffer
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->framebuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
if (rendererData->framebuffers[i] != VK_NULL_HANDLE) {
vkDestroyFramebuffer(rendererData->device, rendererData->framebuffers[i], NULL);
}
}
SDL_free(rendererData->framebuffers);
}
for (uint32_t i = 0; i < SDL_arraysize(rendererData->renderPasses); i++) {
if (rendererData->renderPasses[i] != VK_NULL_HANDLE) {
vkDestroyRenderPass(rendererData->device, rendererData->renderPasses[i], NULL);
rendererData->renderPasses[i] = VK_NULL_HANDLE;
}
}
rendererData->framebuffers = (VkFramebuffer *)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkFramebuffer));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = VULKAN_CreateFramebuffersAndRenderPasses(renderer,
rendererData->swapchainSize.width,
rendererData->swapchainSize.height,
rendererData->surfaceFormat.format,
rendererData->swapchainImageCount,
rendererData->swapchainImageViews,
rendererData->framebuffers,
rendererData->renderPasses);
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_CreateFramebuffersAndRenderPasses(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
// Create descriptor pools - start by allocating one per swapchain image, let it grow if more are needed
if (rendererData->descriptorPools) {
SDL_assert(rendererData->numDescriptorPools);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < rendererData->numDescriptorPools[i]; j++) {
if (rendererData->descriptorPools[i][j] != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(rendererData->device, rendererData->descriptorPools[i][j], NULL);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->descriptorPools[i]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->descriptorPools);
SDL_free(rendererData->numDescriptorPools);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
rendererData->descriptorPools = (VkDescriptorPool **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VkDescriptorPool*));
rendererData->numDescriptorPools = (uint32_t *)SDL_calloc(rendererData->swapchainImageCount, sizeof(uint32_t));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
// Start by just allocating one pool, it will grow if needed
rendererData->numDescriptorPools[i] = 1;
rendererData->descriptorPools[i] = (VkDescriptorPool *)SDL_calloc(1, sizeof(VkDescriptorPool));
rendererData->descriptorPools[i][0] = VULKAN_AllocateDescriptorPool(rendererData);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
return result;
}
}
// Create semaphores
if (rendererData->imageAvailableSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->imageAvailableSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->imageAvailableSemaphores[i], NULL);
}
}
SDL_free(rendererData->imageAvailableSemaphores);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->renderingFinishedSemaphores) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
if (rendererData->renderingFinishedSemaphores[i] != VK_NULL_HANDLE) {
vkDestroySemaphore(rendererData->device, rendererData->renderingFinishedSemaphores[i], NULL);
}
}
SDL_free(rendererData->renderingFinishedSemaphores);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
rendererData->imageAvailableSemaphores = (VkSemaphore *)SDL_calloc(sizeof(VkSemaphore), rendererData->swapchainImageCount);
rendererData->renderingFinishedSemaphores = (VkSemaphore *)SDL_calloc(sizeof(VkSemaphore), rendererData->swapchainImageCount);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
rendererData->imageAvailableSemaphores[i] = VULKAN_CreateSemaphore(rendererData);
if (rendererData->imageAvailableSemaphores[i] == VK_NULL_HANDLE) {
VULKAN_DestroyAll(renderer);
return VK_ERROR_UNKNOWN;
}
rendererData->renderingFinishedSemaphores[i] = VULKAN_CreateSemaphore(rendererData);
if (rendererData->renderingFinishedSemaphores[i] == VK_NULL_HANDLE) {
VULKAN_DestroyAll(renderer);
return VK_ERROR_UNKNOWN;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// Upload buffers
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->uploadBuffers) {
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
for (uint32_t j = 0; j < SDL_VULKAN_NUM_UPLOAD_BUFFERS; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->uploadBuffers[i][j]);
}
SDL_free(rendererData->uploadBuffers[i]);
}
SDL_free(rendererData->uploadBuffers);
}
rendererData->uploadBuffers = (VULKAN_Buffer **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VULKAN_Buffer*));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
rendererData->uploadBuffers[i] = (VULKAN_Buffer *)SDL_calloc(SDL_VULKAN_NUM_UPLOAD_BUFFERS, sizeof(VULKAN_Buffer));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->currentUploadBuffer);
rendererData->currentUploadBuffer = (int *)SDL_calloc(rendererData->swapchainImageCount, sizeof(int));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Constant buffers
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->constantBuffers) {
SDL_assert(rendererData->numConstantBuffers);
for (uint32_t i = 0; i < rendererData->swapchainImageCount; ++i) {
for (uint32_t j = 0; j < rendererData->numConstantBuffers[i]; j++) {
VULKAN_DestroyBuffer(rendererData, &rendererData->constantBuffers[i][j]);
}
SDL_free(rendererData->constantBuffers[i]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_free(rendererData->constantBuffers);
SDL_free(rendererData->numConstantBuffers);
rendererData->constantBuffers = NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
rendererData->constantBuffers = (VULKAN_Buffer **)SDL_calloc(rendererData->swapchainImageCount, sizeof(VULKAN_Buffer*));
rendererData->numConstantBuffers = (uint32_t *)SDL_calloc(rendererData->swapchainImageCount, sizeof(uint32_t));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
for (uint32_t i = 0; i < rendererData->swapchainImageCount; i++) {
// Start with just allocating one, will grow if needed
rendererData->numConstantBuffers[i] = 1;
rendererData->constantBuffers[i] = (VULKAN_Buffer *)SDL_calloc(1, sizeof(VULKAN_Buffer));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = VULKAN_AllocateBuffer(rendererData,
SDL_VULKAN_CONSTANT_BUFFER_DEFAULT_SIZE,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&rendererData->constantBuffers[i][0]);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (result != VK_SUCCESS) {
VULKAN_DestroyAll(renderer);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateBuffer(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
}
rendererData->currentConstantBufferOffset = -1;
rendererData->currentConstantBufferIndex = 0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_AcquireNextSwapchainImage(renderer);
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_VULKAN_SWAPCHAIN_IMAGE_COUNT_NUMBER, rendererData->swapchainImageCount);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return result;
}
// Initialize all resources that change when the window's size changes.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static VkResult VULKAN_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result = VK_SUCCESS;
int w, h;
// Release resources in the current command list
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_IssueBatch(rendererData);
VULKAN_WaitForGPU(rendererData);
/* The width and height of the swap chain must be based on the display's
* non-rotated size.
*/
SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
result = VULKAN_CreateSwapChain(renderer, w, h);
if (result != VK_SUCCESS) {
rendererData->recreateSwapchain = VK_TRUE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
2024-08-22 09:21:26 -07:00
rendererData->viewportDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return result;
}
// This method is called when the window's size changes.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static VkResult VULKAN_UpdateForWindowSizeChange(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
// If the GPU has previous work, wait for it to be done first
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_WaitForGPU(rendererData);
return VULKAN_CreateWindowSizeDependentResources(renderer);
}
static void VULKAN_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) {
2024-08-22 09:21:26 -07:00
rendererData->recreateSwapchain = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
if (GetBlendFactor(srcColorFactor) == VK_BLEND_FACTOR_MAX_ENUM ||
GetBlendFactor(srcAlphaFactor) == VK_BLEND_FACTOR_MAX_ENUM ||
GetBlendOp(colorOperation) == VK_BLEND_OP_MAX_ENUM ||
GetBlendFactor(dstColorFactor) == VK_BLEND_FACTOR_MAX_ENUM ||
GetBlendFactor(dstAlphaFactor) == VK_BLEND_FACTOR_MAX_ENUM ||
GetBlendOp(alphaOperation) == VK_BLEND_OP_MAX_ENUM) {
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_TextureData *textureData;
VkResult result;
VkFormat textureFormat = SDLPixelFormatToVkTextureFormat(texture->format, renderer->output_colorspace);
uint32_t width = texture->w;
uint32_t height = texture->h;
VkComponentMapping imageViewSwizzle = rendererData->identitySwizzle;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (textureFormat == VK_FORMAT_UNDEFINED) {
return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", __FUNCTION__, texture->format);
}
textureData = (VULKAN_TextureData *)SDL_calloc(1, sizeof(*textureData));
if (!textureData) {
return -1;
}
texture->internal = textureData;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (SDL_COLORSPACETRANSFER(texture->colorspace) == SDL_TRANSFER_CHARACTERISTICS_SRGB) {
textureData->shader = SHADER_RGB;
} else {
textureData->shader = SHADER_ADVANCED;
}
textureData->scaleMode = (texture->scaleMode == SDL_SCALEMODE_NEAREST) ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
#if SDL_HAVE_YUV
// YUV textures must have even width and height. Also create Ycbcr conversion
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV ||
texture->format == SDL_PIXELFORMAT_NV12 ||
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
texture->format == SDL_PIXELFORMAT_NV21 ||
texture->format == SDL_PIXELFORMAT_P010) {
const uint32_t YUV_SD_THRESHOLD = 576;
// Check that we have VK_KHR_sampler_ycbcr_conversion support
if (!rendererData->supportsKHRSamplerYCbCrConversion) {
return SDL_SetError("[Vulkan] YUV textures require a Vulkan device that supports VK_KHR_sampler_ycbcr_conversion");
}
2024-02-28 19:11:33 -08:00
VkSamplerYcbcrConversionCreateInfoKHR samplerYcbcrConversionCreateInfo = { 0 };
samplerYcbcrConversionCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR;
// Pad width/height to multiple of 2
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
width = (width + 1) & ~1;
height = (height + 1) & ~1;
// Create samplerYcbcrConversion which will be used on the VkImageView and VkSampler
samplerYcbcrConversionCreateInfo.format = textureFormat;
switch (SDL_COLORSPACEMATRIX(texture->colorspace)) {
case SDL_MATRIX_COEFFICIENTS_BT470BG:
case SDL_MATRIX_COEFFICIENTS_BT601:
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR;
break;
case SDL_MATRIX_COEFFICIENTS_BT709:
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR;
break;
case SDL_MATRIX_COEFFICIENTS_BT2020_NCL:
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR;
2024-02-28 19:11:33 -08:00
break;
case SDL_MATRIX_COEFFICIENTS_UNSPECIFIED:
if (texture->format == SDL_PIXELFORMAT_P010) {
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR;
} else if (height > YUV_SD_THRESHOLD) {
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR;
} else {
samplerYcbcrConversionCreateInfo.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR;
}
break;
default:
2024-02-28 19:11:33 -08:00
return SDL_SetError("[Vulkan] Unsupported Ycbcr colorspace: %d", SDL_COLORSPACEMATRIX(texture->colorspace));
}
samplerYcbcrConversionCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
samplerYcbcrConversionCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
samplerYcbcrConversionCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
samplerYcbcrConversionCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_NV21) {
samplerYcbcrConversionCreateInfo.components.r = VK_COMPONENT_SWIZZLE_B;
samplerYcbcrConversionCreateInfo.components.b = VK_COMPONENT_SWIZZLE_R;
}
switch (SDL_COLORSPACERANGE(texture->colorspace)) {
case SDL_COLOR_RANGE_LIMITED:
samplerYcbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR;
break;
case SDL_COLOR_RANGE_FULL:
default:
samplerYcbcrConversionCreateInfo.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR;
break;
}
switch (SDL_COLORSPACECHROMA(texture->colorspace)) {
case SDL_CHROMA_LOCATION_LEFT:
samplerYcbcrConversionCreateInfo.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN_KHR;
samplerYcbcrConversionCreateInfo.yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT_KHR;
break;
case SDL_CHROMA_LOCATION_TOPLEFT:
samplerYcbcrConversionCreateInfo.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN_KHR;
samplerYcbcrConversionCreateInfo.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN_KHR;
break;
case SDL_CHROMA_LOCATION_NONE:
case SDL_CHROMA_LOCATION_CENTER:
default:
samplerYcbcrConversionCreateInfo.xChromaOffset = VK_CHROMA_LOCATION_MIDPOINT_KHR;
samplerYcbcrConversionCreateInfo.yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT_KHR;
break;
}
samplerYcbcrConversionCreateInfo.chromaFilter = VK_FILTER_LINEAR;
samplerYcbcrConversionCreateInfo.forceExplicitReconstruction = VK_FALSE;
result = vkCreateSamplerYcbcrConversionKHR(rendererData->device, &samplerYcbcrConversionCreateInfo, NULL, &textureData->samplerYcbcrConversion);
if (result != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
return SDL_SetError("[Vulkan] vkCreateSamplerYcbcrConversionKHR %s", SDL_Vulkan_GetResultString(result));
}
// Also create VkSampler object which we will need to pass to the PSO as an immutable sampler
VkSamplerCreateInfo samplerCreateInfo = { 0 };
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerCreateInfo.mipLodBias = 0.0f;
samplerCreateInfo.anisotropyEnable = VK_FALSE;
samplerCreateInfo.maxAnisotropy = 1.0f;
samplerCreateInfo.minLod = 0.0f;
samplerCreateInfo.maxLod = 1000.0f;
VkSamplerYcbcrConversionInfoKHR samplerYcbcrConversionInfo = { 0 };
samplerYcbcrConversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR;
samplerYcbcrConversionInfo.conversion = textureData->samplerYcbcrConversion;
samplerCreateInfo.pNext = &samplerYcbcrConversionInfo;
result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &textureData->samplerYcbcr);
if (result != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
return SDL_SetError("[Vulkan] vkCreateSampler %s", SDL_Vulkan_GetResultString(result));
}
// Allocate special descriptor set layout with samplerYcbcr baked as an immutable sampler
result = VULKAN_CreateDescriptorSetAndPipelineLayout(rendererData, textureData->samplerYcbcr,
&textureData->descriptorSetLayoutYcbcr, &textureData->pipelineLayoutYcbcr);
if (result != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
return SDL_SetError("[Vulkan] VULKAN_CreateDescriptorSetAndPipelineLayout %s", SDL_Vulkan_GetResultString(result));
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
#endif
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
textureData->width = width;
textureData->height = height;
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
}
result = VULKAN_AllocateImage(rendererData, create_props, width, height, textureFormat, usage, imageViewSwizzle, textureData->samplerYcbcrConversion, &textureData->mainImage);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateImage(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
SDL_PropertiesID props = SDL_GetTextureProperties(texture);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER, (Sint64)textureData->mainImage.image);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
result = VULKAN_CreateFramebuffersAndRenderPasses(renderer,
texture->w,
texture->h,
textureFormat,
1,
&textureData->mainImage.imageView,
&textureData->mainFramebuffer,
textureData->mainRenderpasses);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_CreateFramebuffersAndRenderPasses(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
}
return result;
}
static void VULKAN_DestroyTexture(SDL_Renderer *renderer,
SDL_Texture *texture)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return;
}
/* Because SDL_DestroyTexture might be called while the data is in-flight, we need to issue the batch first
Unfortunately, this means that deleting a lot of textures mid-frame will have poor performance. */
VULKAN_IssueBatch(rendererData);
VULKAN_WaitForGPU(rendererData);
VULKAN_DestroyImage(rendererData, &textureData->mainImage);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
#if SDL_HAVE_YUV
if (textureData->samplerYcbcrConversion != VK_NULL_HANDLE) {
vkDestroySamplerYcbcrConversionKHR(rendererData->device, textureData->samplerYcbcrConversion, NULL);
textureData->samplerYcbcrConversion = VK_NULL_HANDLE;
}
if (textureData->samplerYcbcr != VK_NULL_HANDLE) {
vkDestroySampler(rendererData->device, textureData->samplerYcbcr, NULL);
textureData->samplerYcbcr = VK_NULL_HANDLE;
}
if (textureData->pipelineLayoutYcbcr != VK_NULL_HANDLE) {
vkDestroyPipelineLayout(rendererData->device, textureData->pipelineLayoutYcbcr, NULL);
textureData->pipelineLayoutYcbcr = VK_NULL_HANDLE;
}
if (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE) {
vkDestroyDescriptorSetLayout(rendererData->device, textureData->descriptorSetLayoutYcbcr, NULL);
textureData->descriptorSetLayoutYcbcr = VK_NULL_HANDLE;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
#endif
VULKAN_DestroyBuffer(rendererData, &textureData->stagingBuffer);
if (textureData->mainFramebuffer != VK_NULL_HANDLE) {
vkDestroyFramebuffer(rendererData->device, textureData->mainFramebuffer, NULL);
textureData->mainFramebuffer = VK_NULL_HANDLE;
}
for (uint32_t i = 0; i < SDL_arraysize(textureData->mainRenderpasses); i++) {
if (textureData->mainRenderpasses[i] != VK_NULL_HANDLE) {
vkDestroyRenderPass(rendererData->device, textureData->mainRenderpasses[i], NULL);
textureData->mainRenderpasses[i] = VK_NULL_HANDLE;
}
}
SDL_free(textureData);
texture->internal = NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static VkResult VULKAN_UpdateTextureInternal(VULKAN_RenderData *rendererData, VkImage image, VkFormat format, int plane, int x, int y, int w, int h, const void *pixels, int pitch, VkImageLayout *imageLayout)
{
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(format);
VkDeviceSize length = w * pixelSize;
VkDeviceSize uploadBufferSize = length * h;
const Uint8 *src;
Uint8 *dst;
VkResult result;
int planeCount = VULKAN_VkFormatGetNumPlanes(format);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_EnsureCommandBuffer(rendererData);
int currentUploadBufferIndex = rendererData->currentUploadBuffer[rendererData->currentCommandBufferIndex];
VULKAN_Buffer *uploadBuffer = &rendererData->uploadBuffers[rendererData->currentCommandBufferIndex][currentUploadBufferIndex];
result = VULKAN_AllocateBuffer(rendererData, uploadBufferSize,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
uploadBuffer);
if (result != VK_SUCCESS) {
return result;
}
src = (const Uint8 *)pixels;
dst = (Uint8 *)uploadBuffer->mappedBufferPtr;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (length == (VkDeviceSize)pitch) {
SDL_memcpy(dst, src, (size_t)length * h);
} else {
if (length > (VkDeviceSize)pitch) {
length = pitch;
}
for (VkDeviceSize row = h; row--; ) {
SDL_memcpy(dst, src, (size_t)length);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
src += pitch;
dst += length;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
// Make sure the destination is in the correct resource state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
image,
imageLayout);
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageSubresource.mipLevel = 0;
if (planeCount <= 1) {
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
else {
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT << plane;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
region.imageOffset.x = x;
region.imageOffset.y = y;
region.imageOffset.z = 0;
region.imageExtent.width = w;
region.imageExtent.height = h;
region.imageExtent.depth = 1;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkCmdCopyBufferToImage(rendererData->currentCommandBuffer, uploadBuffer->buffer, image, *imageLayout, 1, &region);
// Transition the texture to be shader accessible
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
image,
imageLayout);
rendererData->currentUploadBuffer[rendererData->currentCommandBufferIndex]++;
// If we've used up all the upload buffers, we need to issue the batch
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->currentUploadBuffer[rendererData->currentCommandBufferIndex] == SDL_VULKAN_NUM_UPLOAD_BUFFERS) {
VULKAN_IssueBatch(rendererData);
}
return VK_SUCCESS;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, const void *srcPixels,
int srcPitch)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return SDL_SetError("Texture is not currently available");
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 0, rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch, &textureData->mainImage.imageLayout) < 0) {
return -1;
}
#if SDL_HAVE_YUV
Uint32 numPlanes = VULKAN_VkFormatGetNumPlanes(textureData->mainImage.format);
// Skip to the correct offset into the next texture
srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch);
// YUV data
if (numPlanes == 3) {
for (Uint32 plane = 1; plane < numPlanes; plane++) {
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, plane, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2, &textureData->mainImage.imageLayout) < 0) {
return -1;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
// Skip to the correct offset into the next texture
srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2));
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
// NV12/NV21 data
else if (numPlanes == 2)
{
if (texture->format == SDL_PIXELFORMAT_P010) {
srcPitch = (srcPitch + 3) & ~3;
} else {
srcPitch = (srcPitch + 1) & ~1;
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, srcPitch, &textureData->mainImage.imageLayout) < 0) {
return -1;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
#endif
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
#if SDL_HAVE_YUV
static int VULKAN_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return SDL_SetError("Texture is not currently available");
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 0, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainImage.imageLayout) < 0) {
return -1;
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch, &textureData->mainImage.imageLayout) < 0) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return -1;
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 2, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch, &textureData->mainImage.imageLayout) < 0) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return -1;
}
return 0;
}
static int VULKAN_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return SDL_SetError("Texture is not currently available");
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 0, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainImage.imageLayout) < 0) {
return -1;
}
if (VULKAN_UpdateTextureInternal(rendererData, textureData->mainImage.image, textureData->mainImage.format, 1, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, UVplane, UVpitch, &textureData->mainImage.imageLayout) < 0) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return -1;
}
return 0;
}
#endif
static int VULKAN_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result;
if (!textureData) {
return SDL_SetError("Texture is not currently available");
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (textureData->stagingBuffer.buffer != VK_NULL_HANDLE) {
return SDL_SetError("texture is already locked");
}
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(textureData->mainImage.format);
VkDeviceSize length = rect->w * pixelSize;
VkDeviceSize stagingBufferSize = length * rect->h;
result = VULKAN_AllocateBuffer(rendererData,
stagingBufferSize,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
&textureData->stagingBuffer);
if (result != VK_SUCCESS) {
return SDL_SetError("[Vulkan] VULKAN_AllocateBuffer with result %s", SDL_Vulkan_GetResultString(result));
}
/* Make note of where the staging texture will be written to
* (on a call to SDL_UnlockTexture):
*/
textureData->lockedRect = *rect;
/* Make sure the caller has information on the texture's pixel buffer,
* then return:
*/
*pixels = textureData->stagingBuffer.mappedBufferPtr;
2024-07-13 08:59:25 -07:00
*pitch = (int)length;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static void VULKAN_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return;
}
VULKAN_EnsureCommandBuffer(rendererData);
// Make sure the destination is in the correct resource state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
textureData->mainImage.image,
&textureData->mainImage.imageLayout);
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageOffset.x = textureData->lockedRect.x;
region.imageOffset.y = textureData->lockedRect.y;
region.imageOffset.z = 0;
region.imageExtent.width = textureData->lockedRect.w;
region.imageExtent.height = textureData->lockedRect.h;
region.imageExtent.depth = 1;
vkCmdCopyBufferToImage(rendererData->currentCommandBuffer, textureData->stagingBuffer.buffer, textureData->mainImage.image, textureData->mainImage.imageLayout, 1, &region);
// Transition the texture to be shader accessible
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
textureData->mainImage.image,
&textureData->mainImage.imageLayout);
// Execute the command list before releasing the staging buffer
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_IssueBatch(rendererData);
VULKAN_DestroyBuffer(rendererData, &textureData->stagingBuffer);
}
static void VULKAN_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
{
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!textureData) {
return;
}
textureData->scaleMode = (scaleMode == SDL_SCALEMODE_NEAREST) ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
}
static int VULKAN_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_TextureData *textureData = NULL;
VULKAN_EnsureCommandBuffer(rendererData);
if (!texture) {
if (rendererData->textureRenderTarget) {
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
rendererData->textureRenderTarget->mainImage.image,
&rendererData->textureRenderTarget->mainImage.imageLayout);
}
rendererData->textureRenderTarget = NULL;
return 0;
}
textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (textureData->mainImage.imageView == VK_NULL_HANDLE) {
return SDL_SetError("specified texture is not a render target");
}
rendererData->textureRenderTarget = textureData;
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
rendererData->textureRenderTarget->mainImage.image,
&rendererData->textureRenderTarget->mainImage.imageLayout);
return 0;
}
static int VULKAN_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
return 0; // nothing to do in this backend.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
{
VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
int i;
2024-08-22 09:21:26 -07:00
bool convert_color = SDL_RenderingLinearSpace(renderer);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
for (i = 0; i < count; i++) {
verts->pos[0] = points[i].x + 0.5f;
verts->pos[1] = points[i].y + 0.5f;
verts->tex[0] = 0.0f;
verts->tex[1] = 0.0f;
verts->color = cmd->data.draw.color;
if (convert_color) {
SDL_ConvertToLinear(&verts->color);
}
verts++;
}
return 0;
}
static int VULKAN_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
float scale_x, float scale_y)
{
int i;
int count = indices ? num_indices : num_vertices;
VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
2024-08-22 09:21:26 -07:00
bool convert_color = SDL_RenderingLinearSpace(renderer);
VULKAN_TextureData *textureData = texture ? (VULKAN_TextureData *)texture->internal : NULL;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
float u_scale = textureData ? (float)texture->w / textureData->width : 0.0f;
float v_scale = textureData ? (float)texture->h / textureData->height : 0.0f;
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
size_indices = indices ? size_indices : 0;
for (i = 0; i < count; i++) {
int j;
float *xy_;
if (size_indices == 4) {
j = ((const Uint32 *)indices)[i];
} else if (size_indices == 2) {
j = ((const Uint16 *)indices)[i];
} else if (size_indices == 1) {
j = ((const Uint8 *)indices)[i];
} else {
j = i;
}
xy_ = (float *)((char *)xy + j * xy_stride);
verts->pos[0] = xy_[0] * scale_x;
verts->pos[1] = xy_[1] * scale_y;
verts->color = *(SDL_FColor *)((char *)color + j * color_stride);
if (convert_color) {
SDL_ConvertToLinear(&verts->color);
}
if (texture) {
float *uv_ = (float *)((char *)uv + j * uv_stride);
verts->tex[0] = uv_[0] * u_scale;
verts->tex[1] = uv_[1] * v_scale;
} else {
verts->tex[0] = 0.0f;
verts->tex[1] = 0.0f;
}
verts += 1;
}
return 0;
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_UpdateVertexBuffer(SDL_Renderer *renderer,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const void *vertexData, size_t dataSizeInBytes, VULKAN_DrawStateCache *stateCache)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const int vbidx = rendererData->currentVertexBuffer;
VULKAN_Buffer *vertexBuffer;
if (dataSizeInBytes == 0) {
return true; // nothing to do.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->issueBatch) {
if (VULKAN_IssueBatch(rendererData) != VK_SUCCESS) {
SDL_SetError("Failed to issue intermediate batch");
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
// If the existing vertex buffer isn't big enough, we need to recreate a big enough one
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (dataSizeInBytes > rendererData->vertexBuffers[vbidx].size) {
VULKAN_IssueBatch(rendererData);
VULKAN_WaitForGPU(rendererData);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_CreateVertexBuffer(rendererData, vbidx, dataSizeInBytes);
}
vertexBuffer = &rendererData->vertexBuffers[vbidx];
SDL_memcpy(vertexBuffer->mappedBufferPtr, vertexData, dataSizeInBytes);
stateCache->vertexBuffer = vertexBuffer->buffer;
rendererData->currentVertexBuffer++;
if (rendererData->currentVertexBuffer >= SDL_VULKAN_NUM_VERTEX_BUFFERS) {
rendererData->currentVertexBuffer = 0;
2024-08-22 09:21:26 -07:00
rendererData->issueBatch = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_UpdateViewport(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const SDL_Rect *viewport = &rendererData->currentViewport;
Float4X4 projection;
Float4X4 view;
if (viewport->w == 0 || viewport->h == 0) {
/* If the viewport is empty, assume that it is because
* SDL_CreateRenderer is calling it, and will call it again later
* with a non-empty viewport.
*/
// SDL_Log("%s, no viewport was set!\n", __FUNCTION__);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return -1;
}
projection = MatrixIdentity();
// Update the view matrix
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_zero(view);
view.m[0][0] = 2.0f / viewport->w;
view.m[1][1] = -2.0f / viewport->h;
view.m[2][2] = 1.0f;
view.m[3][0] = -1.0f;
view.m[3][1] = 1.0f;
view.m[3][3] = 1.0f;
rendererData->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
view,
projection);
VkViewport vkViewport;
vkViewport.x = viewport->x;
vkViewport.y = viewport->y;
vkViewport.width = viewport->w;
vkViewport.height = viewport->h;
vkViewport.minDepth = 0.0f;
vkViewport.maxDepth = 1.0f;
vkCmdSetViewport(rendererData->currentCommandBuffer, 0, 1, &vkViewport);
2024-08-22 09:21:26 -07:00
rendererData->viewportDirty = false;
return 0;
}
static int VULKAN_UpdateClipRect(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
const SDL_Rect *viewport = &rendererData->currentViewport;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkRect2D scissor;
if (rendererData->currentCliprectEnabled) {
scissor.offset.x = viewport->x + rendererData->currentCliprect.x;
scissor.offset.y = viewport->y + rendererData->currentCliprect.y;
scissor.extent.width = rendererData->currentCliprect.w;
scissor.extent.height = rendererData->currentCliprect.h;
} else {
scissor.offset.x = viewport->x;
scissor.offset.y = viewport->y;
scissor.extent.width = viewport->w;
scissor.extent.height = viewport->h;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
vkCmdSetScissor(rendererData->currentCommandBuffer, 0, 1, &scissor);
2024-08-22 09:21:26 -07:00
rendererData->cliprectDirty = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static void VULKAN_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Texture *texture, PixelShaderConstants *constants)
{
float output_headroom;
SDL_zerop(constants);
constants->scRGB_output = (float)SDL_RenderingLinearSpace(renderer);
constants->color_scale = cmd->data.draw.color_scale;
if (texture) {
switch (texture->format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
constants->input_type = INPUTTYPE_SRGB;
break;
case SDL_PIXELFORMAT_P010:
constants->input_type = INPUTTYPE_HDR10;
break;
default:
if (texture->colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
constants->input_type = INPUTTYPE_SCRGB;
} else if (SDL_COLORSPACEPRIMARIES(texture->colorspace) == SDL_COLOR_PRIMARIES_BT2020 &&
SDL_COLORSPACETRANSFER(texture->colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
constants->input_type = INPUTTYPE_HDR10;
} else {
constants->input_type = INPUTTYPE_UNSPECIFIED;
}
break;
}
constants->sdr_white_point = texture->SDR_white_point;
if (renderer->target) {
output_headroom = renderer->target->HDR_headroom;
} else {
output_headroom = renderer->HDR_headroom;
}
if (texture->HDR_headroom > output_headroom) {
constants->tonemap_method = TONEMAP_CHROME;
constants->tonemap_factor1 = (output_headroom / (texture->HDR_headroom * texture->HDR_headroom));
constants->tonemap_factor2 = (1.0f / output_headroom);
}
}
}
static VkDescriptorPool VULKAN_AllocateDescriptorPool(VULKAN_RenderData *rendererData)
{
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
2024-07-13 17:24:22 +05:30
VkDescriptorPoolSize descriptorPoolSizes[3];
VkResult result;
descriptorPoolSizes[0].descriptorCount = SDL_VULKAN_MAX_DESCRIPTOR_SETS;
descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLER;
descriptorPoolSizes[1].descriptorCount = SDL_VULKAN_MAX_DESCRIPTOR_SETS;
descriptorPoolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2024-07-13 17:24:22 +05:30
descriptorPoolSizes[2].descriptorCount = SDL_VULKAN_MAX_DESCRIPTOR_SETS;
descriptorPoolSizes[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { 0 };
descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolCreateInfo.poolSizeCount = SDL_arraysize(descriptorPoolSizes);
descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
descriptorPoolCreateInfo.maxSets = SDL_VULKAN_MAX_DESCRIPTOR_SETS;
result = vkCreateDescriptorPool(rendererData->device, &descriptorPoolCreateInfo, NULL, &descriptorPool);
if (result != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
SDL_SetError("[Vulkan] Unable to allocate descriptor pool vkCreateDescrptorPool: %s", SDL_Vulkan_GetResultString(result));
return VK_NULL_HANDLE;
}
return descriptorPool;
}
static VkResult VULKAN_CreateDescriptorSetAndPipelineLayout(VULKAN_RenderData *rendererData, VkSampler samplerYcbcr, VkDescriptorSetLayout *descriptorSetLayoutOut,
VkPipelineLayout *pipelineLayoutOut)
{
VkResult result;
// Descriptor set layout
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = { 0 };
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.flags = 0;
VkDescriptorSetLayoutBinding layoutBindings[2];
// PixelShaderConstants
layoutBindings[0].binding = 1;
layoutBindings[0].descriptorCount = 1;
layoutBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
layoutBindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
layoutBindings[0].pImmutableSamplers = NULL;
// Combined image/sampler
layoutBindings[1].binding = 0;
layoutBindings[1].descriptorCount = 1;
layoutBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
layoutBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
layoutBindings[1].pImmutableSamplers = (samplerYcbcr != VK_NULL_HANDLE) ? &samplerYcbcr : NULL;
descriptorSetLayoutCreateInfo.bindingCount = 2;
descriptorSetLayoutCreateInfo.pBindings = layoutBindings;
result = vkCreateDescriptorSetLayout(rendererData->device, &descriptorSetLayoutCreateInfo, NULL, descriptorSetLayoutOut);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateDescriptorSetLayout(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
// Pipeline layout
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { 0 };
VkPushConstantRange pushConstantRange;
pushConstantRange.size = sizeof( VertexShaderConstants );
pushConstantRange.offset = 0;
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCreateInfo.setLayoutCount = 1;
pipelineLayoutCreateInfo.pSetLayouts = descriptorSetLayoutOut;
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
result = vkCreatePipelineLayout(rendererData->device, &pipelineLayoutCreateInfo, NULL, pipelineLayoutOut);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreatePipelineLayout(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
return result;
}
static VkDescriptorSet VULKAN_AllocateDescriptorSet(SDL_Renderer *renderer, VULKAN_Shader shader, VkDescriptorSetLayout descriptorSetLayout,
VkSampler sampler, VkBuffer constantBuffer, VkDeviceSize constantBufferOffset, VkImageView imageView)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
uint32_t currentDescriptorPoolIndex = rendererData->currentDescriptorPoolIndex;
VkDescriptorPool descriptorPool = rendererData->descriptorPools[rendererData->currentCommandBufferIndex][currentDescriptorPoolIndex];
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { 0 };
descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
descriptorSetAllocateInfo.descriptorSetCount = 1;
descriptorSetAllocateInfo.descriptorPool = descriptorPool;
descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayout;
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
VkResult result = (rendererData->currentDescriptorSetIndex >= SDL_VULKAN_MAX_DESCRIPTOR_SETS) ? VK_ERROR_OUT_OF_DEVICE_MEMORY : VK_SUCCESS;
if (result == VK_SUCCESS) {
result = vkAllocateDescriptorSets(rendererData->device, &descriptorSetAllocateInfo, &descriptorSet);
}
if (result != VK_SUCCESS) {
// Out of descriptor sets in this pool - see if we have more pools allocated
currentDescriptorPoolIndex++;
if (currentDescriptorPoolIndex < rendererData->numDescriptorPools[rendererData->currentCommandBufferIndex]) {
descriptorPool = rendererData->descriptorPools[rendererData->currentCommandBufferIndex][currentDescriptorPoolIndex];
descriptorSetAllocateInfo.descriptorPool = descriptorPool;
result = vkAllocateDescriptorSets(rendererData->device, &descriptorSetAllocateInfo, &descriptorSet);
if (result != VK_SUCCESS) {
// This should not fail - we are allocating from the front of the descriptor set
2024-02-28 19:11:33 -08:00
SDL_SetError("[Vulkan] Unable to allocate descriptor set");
return VK_NULL_HANDLE;
}
rendererData->currentDescriptorPoolIndex = currentDescriptorPoolIndex;
rendererData->currentDescriptorSetIndex = 0;
}
// We are out of pools, create a new one
else {
descriptorPool = VULKAN_AllocateDescriptorPool(rendererData);
if (descriptorPool == VK_NULL_HANDLE) {
// SDL_SetError called in VULKAN_AllocateDescriptorPool if we failed to allocate a new pool
return VK_NULL_HANDLE;
}
rendererData->numDescriptorPools[rendererData->currentCommandBufferIndex]++;
VkDescriptorPool *descriptorPools = (VkDescriptorPool *)SDL_realloc(rendererData->descriptorPools[rendererData->currentCommandBufferIndex],
sizeof(VkDescriptorPool) * rendererData->numDescriptorPools[rendererData->currentCommandBufferIndex]);
descriptorPools[rendererData->numDescriptorPools[rendererData->currentCommandBufferIndex] - 1] = descriptorPool;
rendererData->descriptorPools[rendererData->currentCommandBufferIndex] = descriptorPools;
rendererData->currentDescriptorPoolIndex = currentDescriptorPoolIndex;
rendererData->currentDescriptorSetIndex = 0;
// Call recursively to allocate from the new pool
return VULKAN_AllocateDescriptorSet(renderer, shader, descriptorSetLayout, sampler, constantBuffer, constantBufferOffset, imageView);
}
}
rendererData->currentDescriptorSetIndex++;
VkDescriptorImageInfo combinedImageSamplerDescriptor = { 0 };
VkDescriptorBufferInfo bufferDescriptor = { 0 };
bufferDescriptor.buffer = constantBuffer;
bufferDescriptor.offset = constantBufferOffset;
bufferDescriptor.range = sizeof(PixelShaderConstants);
VkWriteDescriptorSet descriptorWrites[2];
SDL_memset(descriptorWrites, 0, sizeof(descriptorWrites));
uint32_t descriptorCount = 1; // Always have the uniform buffer
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = descriptorSet;
descriptorWrites[0].dstBinding = 1;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrites[0].pBufferInfo = &bufferDescriptor;
if (sampler != VK_NULL_HANDLE && imageView != VK_NULL_HANDLE) {
descriptorCount++;
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = descriptorSet;
descriptorWrites[1].dstBinding = 0;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].pImageInfo = &combinedImageSamplerDescriptor;
// Ignore the sampler if we're using YcBcCr data since it will be baked in the descriptor set layout
if (descriptorSetLayout == rendererData->descriptorSetLayout) {
combinedImageSamplerDescriptor.sampler = sampler;
}
combinedImageSamplerDescriptor.imageView = imageView;
combinedImageSamplerDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
vkUpdateDescriptorSets(rendererData->device, descriptorCount, descriptorWrites, 0, NULL);
return descriptorSet;
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, VULKAN_Shader shader, VkPipelineLayout pipelineLayout, VkDescriptorSetLayout descriptorSetLayout,
const PixelShaderConstants *shader_constants, VkPrimitiveTopology topology, VkImageView imageView, VkSampler sampler, const Float4X4 *matrix, VULKAN_DrawStateCache *stateCache)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const SDL_BlendMode blendMode = cmd->data.draw.blend;
VkFormat format = rendererData->surfaceFormat.format;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
const Float4X4 *newmatrix = matrix ? matrix : &rendererData->identity;
2024-08-22 09:21:26 -07:00
bool updateConstants = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
PixelShaderConstants solid_constants;
VkDescriptorSet descriptorSet;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkBuffer constantBuffer;
VkDeviceSize constantBufferOffset;
int i;
if (!VULKAN_ActivateCommandBuffer(renderer, VK_ATTACHMENT_LOAD_OP_LOAD, NULL, stateCache)) {
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// See if we need to change the pipeline state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!rendererData->currentPipelineState ||
rendererData->currentPipelineState->shader != shader ||
rendererData->currentPipelineState->blendMode != blendMode ||
rendererData->currentPipelineState->topology != topology ||
rendererData->currentPipelineState->format != format ||
rendererData->currentPipelineState->pipelineLayout != pipelineLayout ||
rendererData->currentPipelineState->descriptorSetLayout != descriptorSetLayout) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentPipelineState = NULL;
for (i = 0; i < rendererData->pipelineStateCount; ++i) {
VULKAN_PipelineState *candidatePiplineState = &rendererData->pipelineStates[i];
if (candidatePiplineState->shader == shader &&
candidatePiplineState->blendMode == blendMode &&
candidatePiplineState->topology == topology &&
candidatePiplineState->format == format &&
candidatePiplineState->pipelineLayout == pipelineLayout &&
candidatePiplineState->descriptorSetLayout == descriptorSetLayout) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentPipelineState = candidatePiplineState;
break;
}
}
// If we didn't find a match, create a new one -- it must mean the blend mode is non-standard
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (!rendererData->currentPipelineState) {
rendererData->currentPipelineState = VULKAN_CreatePipelineState(renderer, shader, pipelineLayout, descriptorSetLayout, blendMode, topology, format);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (!rendererData->currentPipelineState) {
return SDL_SetError("[Vulkan] Unable to create required pipeline state");
}
vkCmdBindPipeline(rendererData->currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, rendererData->currentPipelineState->pipeline);
2024-08-22 09:21:26 -07:00
updateConstants = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (rendererData->viewportDirty) {
if (VULKAN_UpdateViewport(renderer) == 0) {
// vertexShaderConstantsData.projectionAndView has changed
2024-08-22 09:21:26 -07:00
updateConstants = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
}
if (rendererData->cliprectDirty) {
VULKAN_UpdateClipRect(renderer);
}
2024-08-22 09:21:26 -07:00
if (updateConstants == true || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof(*newmatrix)) != 0) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_memcpy(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof(*newmatrix));
vkCmdPushConstants(rendererData->currentCommandBuffer, rendererData->currentPipelineState->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0,
sizeof(rendererData->vertexShaderConstantsData),
&rendererData->vertexShaderConstantsData);
}
if (!shader_constants) {
VULKAN_SetupShaderConstants(renderer, cmd, NULL, &solid_constants);
shader_constants = &solid_constants;
}
constantBuffer = rendererData->constantBuffers[rendererData->currentCommandBufferIndex][rendererData->currentConstantBufferIndex].buffer;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
constantBufferOffset = (rendererData->currentConstantBufferOffset < 0) ? 0 : rendererData->currentConstantBufferOffset;
if (updateConstants ||
SDL_memcmp(shader_constants, &rendererData->currentPipelineState->shader_constants, sizeof(*shader_constants)) != 0) {
if (rendererData->currentConstantBufferOffset == -1) {
// First time, grab offset 0
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentConstantBufferOffset = 0;
constantBufferOffset = 0;
}
else {
// Align the next address to the minUniformBufferOffsetAlignment
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkDeviceSize alignment = rendererData->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
SDL_assert(rendererData->currentConstantBufferOffset >= 0 );
rendererData->currentConstantBufferOffset += (int32_t)(sizeof(PixelShaderConstants) + alignment - 1) & ~(alignment - 1);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
constantBufferOffset = rendererData->currentConstantBufferOffset;
}
// If we have run out of size in this constant buffer, create another if needed
if (rendererData->currentConstantBufferOffset >= SDL_VULKAN_CONSTANT_BUFFER_DEFAULT_SIZE) {
uint32_t newConstantBufferIndex = (rendererData->currentConstantBufferIndex + 1);
// We need a new constant buffer
if (newConstantBufferIndex >= rendererData->numConstantBuffers[rendererData->currentCommandBufferIndex]) {
VULKAN_Buffer newConstantBuffer;
VkResult result = VULKAN_AllocateBuffer(rendererData,
SDL_VULKAN_CONSTANT_BUFFER_DEFAULT_SIZE,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&newConstantBuffer);
if (result != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
SDL_SetError("[Vulkan] Could not allocate new memory for constant buffer" );
2024-08-22 09:21:26 -07:00
return false;
}
rendererData->numConstantBuffers[rendererData->currentCommandBufferIndex]++;
VULKAN_Buffer *newConstantBuffers = (VULKAN_Buffer *)SDL_realloc(rendererData->constantBuffers[rendererData->currentCommandBufferIndex],
sizeof(VULKAN_Buffer) * rendererData->numConstantBuffers[rendererData->currentCommandBufferIndex]);
newConstantBuffers[rendererData->numConstantBuffers[rendererData->currentCommandBufferIndex] - 1] = newConstantBuffer;
rendererData->constantBuffers[rendererData->currentCommandBufferIndex] = newConstantBuffers;
}
rendererData->currentConstantBufferIndex = newConstantBufferIndex;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentConstantBufferOffset = 0;
constantBufferOffset = 0;
constantBuffer = rendererData->constantBuffers[rendererData->currentCommandBufferIndex][rendererData->currentConstantBufferIndex].buffer;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_memcpy(&rendererData->currentPipelineState->shader_constants, shader_constants, sizeof(*shader_constants));
// Upload constants to persistently mapped buffer
uint8_t *dst = (uint8_t *)rendererData->constantBuffers[rendererData->currentCommandBufferIndex][rendererData->currentConstantBufferIndex].mappedBufferPtr;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
dst += constantBufferOffset;
SDL_memcpy(dst, &rendererData->currentPipelineState->shader_constants, sizeof(PixelShaderConstants));
}
// Allocate/update descriptor set with the bindings
descriptorSet = VULKAN_AllocateDescriptorSet(renderer, shader, descriptorSetLayout, sampler, constantBuffer, constantBufferOffset, imageView);
if (descriptorSet == VK_NULL_HANDLE) {
2024-08-22 09:21:26 -07:00
return false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
// Bind the descriptor set with the sampler/UBO/image views
vkCmdBindDescriptorSets(rendererData->currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, rendererData->currentPipelineState->pipelineLayout,
0, 1, &descriptorSet, 0, NULL);
2024-08-22 09:21:26 -07:00
return true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
2024-08-22 09:21:26 -07:00
static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix, VULKAN_DrawStateCache *stateCache)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
SDL_Texture *texture = cmd->data.draw.texture;
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
VULKAN_TextureData *textureData = (VULKAN_TextureData *)texture->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkSampler textureSampler = VK_NULL_HANDLE;
PixelShaderConstants constants;
VkDescriptorSetLayout descriptorSetLayout = (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE) ? textureData->descriptorSetLayoutYcbcr : rendererData->descriptorSetLayout;
VkPipelineLayout pipelineLayout = (textureData->pipelineLayoutYcbcr != VK_NULL_HANDLE) ? textureData->pipelineLayoutYcbcr : rendererData->pipelineLayout;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_SetupShaderConstants(renderer, cmd, texture, &constants);
switch (textureData->scaleMode) {
case VK_FILTER_NEAREST:
switch (cmd->data.draw.texture_address_mode) {
case SDL_TEXTURE_ADDRESS_CLAMP:
textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST_CLAMP];
break;
case SDL_TEXTURE_ADDRESS_WRAP:
textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST_WRAP];
break;
default:
return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
case VK_FILTER_LINEAR:
switch (cmd->data.draw.texture_address_mode) {
case SDL_TEXTURE_ADDRESS_CLAMP:
textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR_CLAMP];
break;
case SDL_TEXTURE_ADDRESS_WRAP:
textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR_WRAP];
break;
default:
return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
default:
2024-02-28 19:11:33 -08:00
return SDL_SetError("Unknown scale mode: %d", textureData->scaleMode);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (textureData->mainImage.imageLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
2024-08-22 09:21:26 -07:00
bool stoppedRenderPass = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->currentRenderPass != VK_NULL_HANDLE) {
vkCmdEndRenderPass(rendererData->currentCommandBuffer);
rendererData->currentRenderPass = VK_NULL_HANDLE;
2024-08-22 09:21:26 -07:00
stoppedRenderPass = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
textureData->mainImage.image,
&textureData->mainImage.imageLayout);
if (stoppedRenderPass) {
VULKAN_BeginRenderPass(rendererData, VK_ATTACHMENT_LOAD_OP_LOAD, NULL);
}
}
return VULKAN_SetDrawState(renderer, cmd, textureData->shader, pipelineLayout, descriptorSetLayout, &constants, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, textureData->mainImage.imageView, textureSampler, matrix, stateCache);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static void VULKAN_DrawPrimitives(SDL_Renderer *renderer, VkPrimitiveTopology primitiveTopology, const size_t vertexStart, const size_t vertexCount)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
vkCmdDraw(rendererData->currentCommandBuffer, (uint32_t)vertexCount, 1, (uint32_t)vertexStart, 0);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static void VULKAN_InvalidateCachedState(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentPipelineState = NULL;
2024-08-22 09:21:26 -07:00
rendererData->cliprectDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DrawStateCache stateCache;
SDL_memset(&stateCache, 0, sizeof(stateCache));
if (rendererData->recreateSwapchain) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (VULKAN_UpdateForWindowSizeChange(renderer) != VK_SUCCESS) {
return -1;
}
2024-08-22 09:21:26 -07:00
rendererData->recreateSwapchain = false;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (!VULKAN_UpdateVertexBuffer(renderer, vertices, vertsize, &stateCache)) {
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return -1;
}
while (cmd) {
switch (cmd->command) {
case SDL_RENDERCMD_SETDRAWCOLOR:
{
break; // this isn't currently used in this render backend.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
case SDL_RENDERCMD_SETVIEWPORT:
{
SDL_Rect *viewport = &rendererData->currentViewport;
if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) {
SDL_copyp(viewport, &cmd->data.viewport.rect);
2024-08-22 09:21:26 -07:00
rendererData->viewportDirty = true;
rendererData->cliprectDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
break;
}
case SDL_RENDERCMD_SETCLIPRECT:
{
const SDL_Rect *rect = &cmd->data.cliprect.rect;
if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) {
rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled;
2024-08-22 09:21:26 -07:00
rendererData->cliprectDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) {
SDL_copyp(&rendererData->currentCliprect, rect);
2024-08-22 09:21:26 -07:00
rendererData->cliprectDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
break;
}
case SDL_RENDERCMD_CLEAR:
{
2024-08-22 09:21:26 -07:00
bool convert_color = SDL_RenderingLinearSpace(renderer);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
SDL_FColor color = cmd->data.color.color;
if (convert_color) {
SDL_ConvertToLinear(&color);
}
color.r *= cmd->data.color.color_scale;
color.g *= cmd->data.color.color_scale;
color.b *= cmd->data.color.color_scale;
VkClearColorValue clearColor;
clearColor.float32[0] = color.r;
clearColor.float32[1] = color.g;
clearColor.float32[2] = color.b;
clearColor.float32[3] = color.a;
VULKAN_ActivateCommandBuffer(renderer, VK_ATTACHMENT_LOAD_OP_CLEAR, &clearColor, &stateCache);
break;
}
case SDL_RENDERCMD_DRAW_POINTS:
{
const size_t count = cmd->data.draw.count;
const size_t first = cmd->data.draw.first;
const size_t start = first / sizeof(VertexPositionColor);
VULKAN_SetDrawState(renderer, cmd, SHADER_SOLID, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, &stateCache);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start, count);
break;
}
case SDL_RENDERCMD_DRAW_LINES:
{
const size_t count = cmd->data.draw.count;
const size_t first = cmd->data.draw.first;
const size_t start = first / sizeof(VertexPositionColor);
const VertexPositionColor *verts = (VertexPositionColor *)(((Uint8 *)vertices) + first);
VULKAN_SetDrawState(renderer, cmd, SHADER_SOLID, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, &stateCache);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, start, count);
if (verts[0].pos[0] != verts[count - 1].pos[0] || verts[0].pos[1] != verts[count - 1].pos[1]) {
VULKAN_SetDrawState(renderer, cmd, SHADER_SOLID, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, &stateCache);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start + (count - 1), 1);
}
break;
}
case SDL_RENDERCMD_FILL_RECTS: // unused
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
case SDL_RENDERCMD_COPY: // unused
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
case SDL_RENDERCMD_COPY_EX: // unused
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
break;
case SDL_RENDERCMD_GEOMETRY:
{
SDL_Texture *texture = cmd->data.draw.texture;
const size_t count = cmd->data.draw.count;
const size_t first = cmd->data.draw.first;
const size_t start = first / sizeof(VertexPositionColor);
if (texture) {
VULKAN_SetCopyState(renderer, cmd, NULL, &stateCache);
} else {
VULKAN_SetDrawState(renderer, cmd, SHADER_SOLID, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, &stateCache);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, start, count);
break;
}
case SDL_RENDERCMD_NO_OP:
break;
}
cmd = cmd->next;
}
return 0;
}
static SDL_Surface* VULKAN_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkImage backBuffer;
VkImageLayout *imageLayout;
VULKAN_Buffer readbackBuffer;
VkDeviceSize pixelSize;
VkDeviceSize length;
VkDeviceSize readbackBufferSize;
VkFormat vkFormat;
SDL_Surface *output;
VULKAN_EnsureCommandBuffer(rendererData);
// Stop any outstanding renderpass if open
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
if (rendererData->currentRenderPass != VK_NULL_HANDLE) {
vkCmdEndRenderPass(rendererData->currentCommandBuffer);
rendererData->currentRenderPass = VK_NULL_HANDLE;
}
if (rendererData->textureRenderTarget) {
backBuffer = rendererData->textureRenderTarget->mainImage.image;
imageLayout = &rendererData->textureRenderTarget->mainImage.imageLayout;
vkFormat = rendererData->textureRenderTarget->mainImage.format;
} else {
backBuffer = rendererData->swapchainImages[rendererData->currentSwapchainImageIndex];
imageLayout = &rendererData->swapchainImageLayouts[rendererData->currentSwapchainImageIndex];
vkFormat = rendererData->surfaceFormat.format;
}
pixelSize = VULKAN_GetBytesPerPixel(vkFormat);
length = rect->w * pixelSize;
readbackBufferSize = length * rect->h;
if (VULKAN_AllocateBuffer(rendererData, readbackBufferSize,
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
&readbackBuffer) != VK_SUCCESS) {
2024-02-28 19:11:33 -08:00
SDL_SetError("[Vulkan] Failed to allocate buffer for readback");
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return NULL;
}
// Make sure the source is in the correct resource state
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
backBuffer,
imageLayout);
// Copy the image to the readback buffer
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageOffset.x = rect->x;
region.imageOffset.y = rect->y;
region.imageOffset.z = 0;
region.imageExtent.width = rect->w;
region.imageExtent.height = rect->h;
region.imageExtent.depth = 1;
vkCmdCopyImageToBuffer(rendererData->currentCommandBuffer, backBuffer, *imageLayout, readbackBuffer.buffer, 1, &region);
// We need to issue the command list for the copy to finish
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_IssueBatch(rendererData);
// Transition the render target back to a render target
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
backBuffer,
imageLayout);
output = SDL_DuplicatePixels(
rect->w, rect->h,
VULKAN_VkFormatToSDLPixelFormat(vkFormat),
renderer->target ? renderer->target->colorspace : renderer->output_colorspace,
readbackBuffer.mappedBufferPtr,
2024-07-13 08:59:25 -07:00
(int)length);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_DestroyBuffer(rendererData, &readbackBuffer);
return output;
}
static int VULKAN_AddVulkanRenderSemaphores(SDL_Renderer *renderer, Uint32 wait_stage_mask, Sint64 wait_semaphore, Sint64 signal_semaphore)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
if (wait_semaphore) {
if (rendererData->waitRenderSemaphoreCount == rendererData->waitRenderSemaphoreMax) {
// Allocate an additional one at the end for the normal present wait
VkPipelineStageFlags *waitDestStageMasks = (VkPipelineStageFlags *)SDL_realloc(rendererData->waitDestStageMasks, (rendererData->waitRenderSemaphoreMax + 2) * sizeof(*waitDestStageMasks));
if (!waitDestStageMasks) {
return -1;
}
rendererData->waitDestStageMasks = waitDestStageMasks;
VkSemaphore *semaphores = (VkSemaphore *)SDL_realloc(rendererData->waitRenderSemaphores, (rendererData->waitRenderSemaphoreMax + 2) * sizeof(*semaphores));
if (!semaphores) {
return -1;
}
rendererData->waitRenderSemaphores = semaphores;
++rendererData->waitRenderSemaphoreMax;
}
rendererData->waitDestStageMasks[rendererData->waitRenderSemaphoreCount] = wait_stage_mask;
rendererData->waitRenderSemaphores[rendererData->waitRenderSemaphoreCount] = (VkSemaphore)wait_semaphore;
++rendererData->waitRenderSemaphoreCount;
}
if (signal_semaphore) {
if (rendererData->signalRenderSemaphoreCount == rendererData->signalRenderSemaphoreMax) {
// Allocate an additional one at the end for the normal present signal
VkSemaphore *semaphores = (VkSemaphore *)SDL_realloc(rendererData->signalRenderSemaphores, (rendererData->signalRenderSemaphoreMax + 2) * sizeof(*semaphores));
if (!semaphores) {
return -1;
}
rendererData->signalRenderSemaphores = semaphores;
++rendererData->signalRenderSemaphoreMax;
}
rendererData->signalRenderSemaphores[rendererData->signalRenderSemaphoreCount] = (VkSemaphore)signal_semaphore;
++rendererData->signalRenderSemaphoreCount;
}
return 0;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
static int VULKAN_RenderPresent(SDL_Renderer *renderer)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkResult result = VK_SUCCESS;
if (rendererData->currentCommandBuffer) {
rendererData->currentPipelineState = VK_NULL_HANDLE;
2024-08-22 09:21:26 -07:00
rendererData->viewportDirty = true;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_RecordPipelineImageBarrier(rendererData,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
rendererData->swapchainImages[rendererData->currentSwapchainImageIndex],
&rendererData->swapchainImageLayouts[rendererData->currentSwapchainImageIndex]);
vkEndCommandBuffer(rendererData->currentCommandBuffer);
result = vkResetFences(rendererData->device, 1, &rendererData->fences[rendererData->currentCommandBufferIndex]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkResetFences(): %s\n", SDL_Vulkan_GetResultString(result));
return -1;
}
VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkSubmitInfo submitInfo = { 0 };
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
if (rendererData->waitRenderSemaphoreCount > 0) {
Uint32 additionalSemaphoreCount = (rendererData->currentImageAvailableSemaphore != VK_NULL_HANDLE) ? 1 : 0;
submitInfo.waitSemaphoreCount = rendererData->waitRenderSemaphoreCount + additionalSemaphoreCount;
if (additionalSemaphoreCount > 0) {
rendererData->waitRenderSemaphores[rendererData->waitRenderSemaphoreCount] = rendererData->currentImageAvailableSemaphore;
rendererData->waitDestStageMasks[rendererData->waitRenderSemaphoreCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
}
submitInfo.pWaitSemaphores = rendererData->waitRenderSemaphores;
submitInfo.pWaitDstStageMask = rendererData->waitDestStageMasks;
rendererData->waitRenderSemaphoreCount = 0;
} else if (rendererData->currentImageAvailableSemaphore != VK_NULL_HANDLE) {
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &rendererData->currentImageAvailableSemaphore;
submitInfo.pWaitDstStageMask = &waitDestStageMask;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &rendererData->currentCommandBuffer;
if (rendererData->signalRenderSemaphoreCount > 0) {
submitInfo.signalSemaphoreCount = rendererData->signalRenderSemaphoreCount + 1;
rendererData->signalRenderSemaphores[rendererData->signalRenderSemaphoreCount] = rendererData->renderingFinishedSemaphores[rendererData->currentCommandBufferIndex];
submitInfo.pSignalSemaphores = rendererData->signalRenderSemaphores;
rendererData->signalRenderSemaphoreCount = 0;
} else {
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &rendererData->renderingFinishedSemaphores[rendererData->currentCommandBufferIndex];
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkQueueSubmit(rendererData->graphicsQueue, 1, &submitInfo, rendererData->fences[rendererData->currentCommandBufferIndex]);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkQueueSubmit(): %s\n", SDL_Vulkan_GetResultString(result));
return -1;
}
rendererData->currentCommandBuffer = VK_NULL_HANDLE;
rendererData->currentImageAvailableSemaphore = VK_NULL_HANDLE;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VkPresentInfoKHR presentInfo = { 0 };
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &rendererData->renderingFinishedSemaphores[rendererData->currentCommandBufferIndex];
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &rendererData->swapchain;
presentInfo.pImageIndices = &rendererData->currentSwapchainImageIndex;
result = vkQueuePresentKHR(rendererData->presentQueue, &presentInfo);
if ((result != VK_SUCCESS) && (result != VK_ERROR_OUT_OF_DATE_KHR) && (result != VK_ERROR_SURFACE_LOST_KHR) && (result != VK_SUBOPTIMAL_KHR )) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkQueuePresentKHR(): %s\n", SDL_Vulkan_GetResultString(result));
return -1;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
rendererData->currentCommandBufferIndex = ( rendererData->currentCommandBufferIndex + 1 ) % rendererData->swapchainImageCount;
// Wait for previous time this command buffer was submitted, will be N frames ago
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
result = vkWaitForFences(rendererData->device, 1, &rendererData->fences[rendererData->currentCommandBufferIndex], VK_TRUE, UINT64_MAX);
if (result != VK_SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkWaitForFences(): %s\n", SDL_Vulkan_GetResultString(result));
return -1;
}
VULKAN_AcquireNextSwapchainImage(renderer);
}
return 0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
static int VULKAN_SetVSync(SDL_Renderer *renderer, const int vsync)
{
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
switch (vsync) {
case -1:
case 0:
case 1:
// Supported
break;
default:
return SDL_Unsupported();
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
if (vsync != rendererData->vsync) {
rendererData->vsync = vsync;
2024-08-22 09:21:26 -07:00
rendererData->recreateSwapchain = true;
}
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
return 0;
}
static int VULKAN_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
{
VULKAN_RenderData *rendererData;
SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR
/*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) {
return SDL_SetError("Unsupported output colorspace");
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
rendererData = (VULKAN_RenderData *)SDL_calloc(1, sizeof(*rendererData));
if (!rendererData) {
return -1;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
rendererData->identity = MatrixIdentity();
rendererData->identitySwizzle.r = VK_COMPONENT_SWIZZLE_IDENTITY;
rendererData->identitySwizzle.g = VK_COMPONENT_SWIZZLE_IDENTITY;
rendererData->identitySwizzle.b = VK_COMPONENT_SWIZZLE_IDENTITY;
rendererData->identitySwizzle.a = VK_COMPONENT_SWIZZLE_IDENTITY;
renderer->WindowEvent = VULKAN_WindowEvent;
renderer->SupportsBlendMode = VULKAN_SupportsBlendMode;
renderer->CreateTexture = VULKAN_CreateTexture;
renderer->UpdateTexture = VULKAN_UpdateTexture;
#if SDL_HAVE_YUV
renderer->UpdateTextureYUV = VULKAN_UpdateTextureYUV;
renderer->UpdateTextureNV = VULKAN_UpdateTextureNV;
#endif
renderer->LockTexture = VULKAN_LockTexture;
renderer->UnlockTexture = VULKAN_UnlockTexture;
renderer->SetTextureScaleMode = VULKAN_SetTextureScaleMode;
renderer->SetRenderTarget = VULKAN_SetRenderTarget;
renderer->QueueSetViewport = VULKAN_QueueNoOp;
renderer->QueueSetDrawColor = VULKAN_QueueNoOp;
renderer->QueueDrawPoints = VULKAN_QueueDrawPoints;
renderer->QueueDrawLines = VULKAN_QueueDrawPoints; // lines and points queue vertices the same way.
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
renderer->QueueGeometry = VULKAN_QueueGeometry;
renderer->InvalidateCachedState = VULKAN_InvalidateCachedState;
renderer->RunCommandQueue = VULKAN_RunCommandQueue;
renderer->RenderReadPixels = VULKAN_RenderReadPixels;
renderer->AddVulkanRenderSemaphores = VULKAN_AddVulkanRenderSemaphores;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
renderer->RenderPresent = VULKAN_RenderPresent;
renderer->DestroyTexture = VULKAN_DestroyTexture;
renderer->DestroyRenderer = VULKAN_DestroyRenderer;
renderer->SetVSync = VULKAN_SetVSync;
renderer->internal = rendererData;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
VULKAN_InvalidateCachedState(renderer);
renderer->name = VULKAN_RenderDriver.name;
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB8888);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB8888);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XBGR2101010);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA64_FLOAT);
SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 16384);
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
/* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
* order to give init functions access to the underlying window handle:
*/
renderer->window = window;
// Initialize Vulkan resources
if (VULKAN_CreateDeviceResources(renderer, create_props) != VK_SUCCESS) {
return -1;
} else if (VULKAN_CreateWindowSizeDependentResources(renderer) != VK_SUCCESS) {
return -1;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
#if SDL_HAVE_YUV
if (rendererData->supportsKHRSamplerYCbCrConversion) {
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
}
#endif
return 0;
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
}
SDL_RenderDriver VULKAN_RenderDriver = {
VULKAN_CreateRenderer, "vulkan"
Vulkan Renderer (#9114) This pull request adds an implementation of a Vulkan Render backend to SDL. I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK). I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed). This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors). The shaders are built using the HLSL frontend of glslang. Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`. The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation. The main differences with the Direct3D12 renderer are: * Having to manage renderpasses for performing clears. There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses. * Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written. * Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12. * For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`. I've verified that `testcolorspace` works with both sRGB and HDR linear. I've tested `testoverlay` works with the various YUV/NV12/NV21 formats. I've tested `testsprite`. I've checked that window resizing and swapchain out-of-date handling when minimizing are working. I've run through `testautomation` with the render tests. I also have run several of the tests with Vulkan validation and synchronization validation. Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
2024-02-22 17:58:11 -05:00
};
#endif // SDL_VIDEO_RENDER_VULKAN