Vulkan Renderer (#9114)

This pull request adds an implementation of a Vulkan Render backend to SDL.  I have so far tested this primarily on Windows, but also smoke tested on Linux and macOS (MoltenVK).  I have not tried it yet on Android, but it should be usable there as well (sans any bugs I missed).  This began as a port of the SDL Direct3D12 Renderer, which is the closest thing to Vulkan as existed in the SDL codebase. The shaders are more or less identical (with the only differences being in descriptor bindings vs root descriptors).  The shaders are built using the HLSL frontend of glslang.

Everything in the code is pure Vulkan 1.0 (no extensions), with the exception of HDR support which requires the Vulkan instance extension `VK_EXT_swapchain_colorspace`.  The code could have been simplified considerably if I used dynamic rendering, push descriptors, extended dynamic state, and other modern Vulkan-isms, but I felt it was more important to make the code as vanilla Vulkan as possible so that it would run on any Vulkan implementation.

The main differences with the Direct3D12 renderer are:
* Having to manage renderpasses for performing clears.  There is likely some optimization that would still remain for more efficient use of TBDR hardware where there might be some unnecessary load/stores, but it does attempt to do clears using renderpasses.
* Constant buffer data couldn't be directly updated in the command buffer since I didn't want to rely on push descriptors, so there is a persistently mapped buffer with increasing offset per swapchain image where CB data gets written.
* Many more resources are dependent on the swapchain resizing due to i.e. Vulkan requiring the VkFramebuffer to reference the VkImageView of the swapchain, so there is a bit more code around handling that than was necessary in D3D12.
* For NV12/NV21 textures, rather than there being plane data in the texture itself, the UV data is placed in a separate `VkImage`/`VkImageView`.

I've verified that `testcolorspace` works with both sRGB and HDR linear.  I've tested `testoverlay` works with the various YUV/NV12/NV21 formats.  I've tested `testsprite`.  I've checked that window resizing and swapchain out-of-date handling when minimizing are working.  I've run through `testautomation` with the render tests.  I also have run several of the tests with Vulkan validation and synchronization validation.  Surely I will have missed some things, but I think it's in a good state to be merged and build out from here.
This commit is contained in:
Dan Ginsburg
2024-02-22 17:58:11 -05:00
committed by GitHub
parent 2f1f55aeb1
commit cab20117e6
23 changed files with 4723 additions and 4 deletions

View File

@@ -1736,6 +1736,18 @@ extern "C" {
*/
#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG"
/**
* A variable controlling whether to enable Vulkan Validation Layers
*
*
* This variable can be set to the following values:
* "0" - Disable Validation Layer use
* "1" - Enable Validation Layer use
*
* By default, SDL does not use Vulkan Validation Layers.
*/
#define SDL_HINT_RENDER_VULKAN_DEBUG "SDL_RENDER_VULKAN_DEBUG"
/**
* A variable specifying which render driver to use.
*

View File

@@ -639,6 +639,17 @@ extern DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureWithProperties(SDL_Rendere
* - `SDL_PROP_TEXTURE_D3D12_TEXTURE_V_POINTER`: the ID3D12Resource associated
* with the V plane of a YUV texture
*
* With the vulkan renderer:
*
* - `SDL_PROP_TEXTURE_VULKAN_TEXTURE_POINTER`: the VkImage associated
* with the texture
* - `SDL_PROP_TEXTURE_VULKAN_TEXTURE_U_POINTER`: the VkImage associated
* with the U plane of a YUV texture
* - `SDL_PROP_TEXTURE_VULKAN_TEXTURE_V_POINTER`: the VkImage associated
* with the V plane of a YUV texture
* - `SDL_PROP_TEXTURE_VULKAN_TEXTURE_UV_POINTER`: the VkImage associated
* with the UV plane of a NV12/NV21 texture
*
* With the opengl renderer:
*
* - `SDL_PROP_TEXTURE_OPENGL_TEXTURE_NUMBER`: the GLuint texture associated
@@ -701,6 +712,10 @@ extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetTextureProperties(SDL_Texture *t
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER "SDL.texture.opengles2.texture_u"
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER "SDL.texture.opengles2.texture_v"
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER "SDL.texture.opengles2.target"
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_POINTER "SDL.texture.vulkan.texture"
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_U_POINTER "SDL.texture.vulkan.texture_u"
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_V_POINTER "SDL.texture.vulkan.texture_v"
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_UV_POINTER "SDL.texture.vulkan.texture_uv"
/**
* Get the renderer that created an SDL_Texture.