SDL: Add the SDL_GPU API

From 2e7d5bb429b5fa9ad9c15e69ca7d952827420a52 Mon Sep 17 00:00:00 2001
From: cosmonaut <[EMAIL REDACTED]>
Date: Mon, 18 Mar 2024 11:43:23 -0700
Subject: [PATCH] Add the SDL_GPU API

Project Lead: Evan Hemsley <evan@moonside.games>

Co-designer, Metal Port, Console Ports:

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>

Production, QA, Debug:

Co-authored-by: Ethan Lee <flibitijibibo@gmail.com>

SDL_Render Driver, Bugfixes:

Co-authored-by: Andrei Alexeyev <akari@taisei-project.org>

Additional D3D12 Programming, Bugfixes:

Co-authored-by: Bart van der Werf <bluelive@gmail.com>

Bugfixes and Feedback:

Co-authored-by: Zakary Strange <zakarystrange@gmail.com>
Co-authored-by: meyraud705 <meyraud705@gmail.com>
Co-authored-by: Joshua T. Fisher <playmer@gmail.com>
Co-authored-by: Topi Ritala <ritalat@fastmail.com>
Co-authored-by: David Gow <david@ingeniumdigital.com>

Original API Proposal:

Co-authored-by: Ryan C. Gordon <icculus@icculus.org>
---
 .gitignore                                    |     2 +
 Android.mk                                    |     2 +
 CMakeLists.txt                                |    39 +
 VisualC-GDK/SDL/SDL.vcxproj                   |    15 +
 VisualC-GDK/SDL/SDL.vcxproj.filters           |     6 +
 VisualC-WinRT/SDL-UWP.vcxproj                 |     4 +
 VisualC/SDL/SDL.vcxproj                       |     7 +
 VisualC/SDL/SDL.vcxproj.filters               |    22 +
 include/SDL3/SDL.h                            |     1 +
 include/SDL3/SDL_gpu.h                        |  2512 ++++
 include/SDL3/SDL_hints.h                      |   163 +-
 include/SDL3/SDL_log.h                        |     7 +-
 include/build_config/SDL_build_config.h.cmake |     7 +
 .../build_config/SDL_build_config_android.h   |     2 +
 include/build_config/SDL_build_config_macos.h |     4 +
 .../build_config/SDL_build_config_windows.h   |     6 +
 .../build_config/SDL_build_config_wingdk.h    |     6 +
 include/build_config/SDL_build_config_xbox.h  |     4 +
 src/SDL_log.c                                 |     2 +
 src/core/SDL_core_unsupported.c               |    10 +
 src/dynapi/SDL_dynapi.sym                     |    81 +
 src/dynapi/SDL_dynapi_overrides.h             |    81 +
 src/dynapi/SDL_dynapi_procs.h                 |    81 +
 src/gpu/SDL_gpu.c                             |  2400 ++++
 src/gpu/SDL_sysgpu.h                          |   779 +
 src/gpu/d3d11/D3D11_Blit.h                    |  1328 ++
 src/gpu/d3d11/SDL_gpu_d3d11.c                 |  6135 ++++++++
 src/gpu/d3d11/compile_shaders.bat             |     7 +
 src/gpu/d3d12/D3D12_Blit.h                    |  2665 ++++
 src/gpu/d3d12/SDL_gpu_d3d12.c                 |  8255 +++++++++++
 src/gpu/d3d12/compile_shaders.bat             |    17 +
 src/gpu/d3d12/compile_shaders_xbox.bat        |    13 +
 src/gpu/d3dcommon/D3D_Blit.hlsl               |    91 +
 src/gpu/metal/Metal_Blit.h                    |  7969 +++++++++++
 src/gpu/metal/Metal_Blit.metal                |    85 +
 src/gpu/metal/SDL_gpu_metal.m                 |  3984 ++++++
 src/gpu/metal/compile_shaders.sh              |    68 +
 src/gpu/vulkan/SDL_gpu_vulkan.c               | 11797 ++++++++++++++++
 src/gpu/vulkan/SDL_gpu_vulkan_vkfuncs.h       |   176 +
 src/render/SDL_d3dmath.h                      |     2 +-
 src/render/SDL_render.c                       |     5 +-
 src/render/SDL_sysrender.h                    |     1 +
 src/render/sdlgpu/SDL_gpu_util.h              |    74 +
 src/render/sdlgpu/SDL_pipeline_gpu.c          |   223 +
 src/render/sdlgpu/SDL_pipeline_gpu.h          |    49 +
 src/render/sdlgpu/SDL_render_gpu.c            |  1303 ++
 src/render/sdlgpu/SDL_shaders_gpu.c           |   241 +
 src/render/sdlgpu/SDL_shaders_gpu.h           |    63 +
 src/render/sdlgpu/shaders/.gitattributes      |     1 +
 src/render/sdlgpu/shaders/.gitignore          |     3 +
 src/render/sdlgpu/shaders/build-shaders.sh    |    85 +
 src/render/sdlgpu/shaders/color.frag          |     9 +
 src/render/sdlgpu/shaders/color.frag.metal.h  |    28 +
 .../sdlgpu/shaders/color.frag.sm50.dxbc.h     |    85 +
 .../sdlgpu/shaders/color.frag.sm60.dxil.h     |   340 +
 src/render/sdlgpu/shaders/color.frag.spv.h    |    29 +
 src/render/sdlgpu/shaders/dxbc50.h            |     6 +
 src/render/sdlgpu/shaders/dxil60.h            |     6 +
 src/render/sdlgpu/shaders/linepoint.vert      |    17 +
 .../sdlgpu/shaders/linepoint.vert.metal.h     |    51 +
 .../sdlgpu/shaders/linepoint.vert.sm50.dxbc.h |   172 +
 .../sdlgpu/shaders/linepoint.vert.sm60.dxil.h |   496 +
 .../sdlgpu/shaders/linepoint.vert.spv.h       |    93 +
 src/render/sdlgpu/shaders/metal.h             |     6 +
 src/render/sdlgpu/shaders/spir-v.h            |     6 +
 src/render/sdlgpu/shaders/texture_rgb.frag    |    12 +
 .../sdlgpu/shaders/texture_rgb.frag.metal.h   |    41 +
 .../shaders/texture_rgb.frag.sm50.dxbc.h      |   123 +
 .../shaders/texture_rgb.frag.sm60.dxil.h      |   465 +
 .../sdlgpu/shaders/texture_rgb.frag.spv.h     |    59 +
 src/render/sdlgpu/shaders/texture_rgba.frag   |    12 +
 .../sdlgpu/shaders/texture_rgba.frag.metal.h  |    40 +
 .../shaders/texture_rgba.frag.sm50.dxbc.h     |   120 +
 .../shaders/texture_rgba.frag.sm60.dxil.h     |   467 +
 .../sdlgpu/shaders/texture_rgba.frag.spv.h    |    50 +
 src/render/sdlgpu/shaders/tri_color.vert      |    17 +
 .../sdlgpu/shaders/tri_color.vert.metal.h     |    48 +
 .../sdlgpu/shaders/tri_color.vert.sm50.dxbc.h |   178 +
 .../sdlgpu/shaders/tri_color.vert.sm60.dxil.h |   515 +
 .../sdlgpu/shaders/tri_color.vert.spv.h       |    89 +
 src/render/sdlgpu/shaders/tri_texture.vert    |    20 +
 .../sdlgpu/shaders/tri_texture.vert.metal.h   |    56 +
 .../shaders/tri_texture.vert.sm50.dxbc.h      |   195 +
 .../shaders/tri_texture.vert.sm60.dxil.h      |   558 +
 .../sdlgpu/shaders/tri_texture.vert.spv.h     |   106 +
 src/video/directx/SDL_d3d12.h                 |    11 +
 test/CMakeLists.txt                           |     1 +
 test/testgpu/build-shaders.sh                 |   103 +
 test/testgpu/cube.glsl                        |    31 +
 test/testgpu/cube.hlsl                        |    35 +
 test/testgpu/cube.metal                       |    38 +
 test/testgpu/testgpu_dxbc.h                   |   333 +
 test/testgpu/testgpu_dxil.h                   |   876 ++
 test/testgpu/testgpu_metallib.h               |  2584 ++++
 test/testgpu/testgpu_spirv.h                  |   150 +
 test/testgpu_spinning_cube.c                  |   724 +
 96 files changed, 60218 insertions(+), 66 deletions(-)
 create mode 100644 include/SDL3/SDL_gpu.h
 create mode 100644 src/gpu/SDL_gpu.c
 create mode 100644 src/gpu/SDL_sysgpu.h
 create mode 100644 src/gpu/d3d11/D3D11_Blit.h
 create mode 100644 src/gpu/d3d11/SDL_gpu_d3d11.c
 create mode 100644 src/gpu/d3d11/compile_shaders.bat
 create mode 100644 src/gpu/d3d12/D3D12_Blit.h
 create mode 100644 src/gpu/d3d12/SDL_gpu_d3d12.c
 create mode 100644 src/gpu/d3d12/compile_shaders.bat
 create mode 100644 src/gpu/d3d12/compile_shaders_xbox.bat
 create mode 100644 src/gpu/d3dcommon/D3D_Blit.hlsl
 create mode 100644 src/gpu/metal/Metal_Blit.h
 create mode 100644 src/gpu/metal/Metal_Blit.metal
 create mode 100644 src/gpu/metal/SDL_gpu_metal.m
 create mode 100755 src/gpu/metal/compile_shaders.sh
 create mode 100644 src/gpu/vulkan/SDL_gpu_vulkan.c
 create mode 100644 src/gpu/vulkan/SDL_gpu_vulkan_vkfuncs.h
 create mode 100644 src/render/sdlgpu/SDL_gpu_util.h
 create mode 100644 src/render/sdlgpu/SDL_pipeline_gpu.c
 create mode 100644 src/render/sdlgpu/SDL_pipeline_gpu.h
 create mode 100644 src/render/sdlgpu/SDL_render_gpu.c
 create mode 100644 src/render/sdlgpu/SDL_shaders_gpu.c
 create mode 100644 src/render/sdlgpu/SDL_shaders_gpu.h
 create mode 100644 src/render/sdlgpu/shaders/.gitattributes
 create mode 100644 src/render/sdlgpu/shaders/.gitignore
 create mode 100755 src/render/sdlgpu/shaders/build-shaders.sh
 create mode 100644 src/render/sdlgpu/shaders/color.frag
 create mode 100644 src/render/sdlgpu/shaders/color.frag.metal.h
 create mode 100644 src/render/sdlgpu/shaders/color.frag.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/color.frag.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/color.frag.spv.h
 create mode 100644 src/render/sdlgpu/shaders/dxbc50.h
 create mode 100644 src/render/sdlgpu/shaders/dxil60.h
 create mode 100644 src/render/sdlgpu/shaders/linepoint.vert
 create mode 100644 src/render/sdlgpu/shaders/linepoint.vert.metal.h
 create mode 100644 src/render/sdlgpu/shaders/linepoint.vert.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/linepoint.vert.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/linepoint.vert.spv.h
 create mode 100644 src/render/sdlgpu/shaders/metal.h
 create mode 100644 src/render/sdlgpu/shaders/spir-v.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgb.frag
 create mode 100644 src/render/sdlgpu/shaders/texture_rgb.frag.metal.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgb.frag.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgb.frag.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgb.frag.spv.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgba.frag
 create mode 100644 src/render/sdlgpu/shaders/texture_rgba.frag.metal.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgba.frag.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgba.frag.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/texture_rgba.frag.spv.h
 create mode 100644 src/render/sdlgpu/shaders/tri_color.vert
 create mode 100644 src/render/sdlgpu/shaders/tri_color.vert.metal.h
 create mode 100644 src/render/sdlgpu/shaders/tri_color.vert.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/tri_color.vert.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/tri_color.vert.spv.h
 create mode 100644 src/render/sdlgpu/shaders/tri_texture.vert
 create mode 100644 src/render/sdlgpu/shaders/tri_texture.vert.metal.h
 create mode 100644 src/render/sdlgpu/shaders/tri_texture.vert.sm50.dxbc.h
 create mode 100644 src/render/sdlgpu/shaders/tri_texture.vert.sm60.dxil.h
 create mode 100644 src/render/sdlgpu/shaders/tri_texture.vert.spv.h
 create mode 100755 test/testgpu/build-shaders.sh
 create mode 100644 test/testgpu/cube.glsl
 create mode 100644 test/testgpu/cube.hlsl
 create mode 100644 test/testgpu/cube.metal
 create mode 100644 test/testgpu/testgpu_dxbc.h
 create mode 100644 test/testgpu/testgpu_dxil.h
 create mode 100644 test/testgpu/testgpu_metallib.h
 create mode 100644 test/testgpu/testgpu_spirv.h
 create mode 100644 test/testgpu_spinning_cube.c

diff --git a/.gitignore b/.gitignore
index 5326a62c39891..3c45e91b757d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,6 +83,8 @@ VisualC/tests/testyuv/testyuv.bmp
 VisualC-GDK/**/Layout
 src/render/direct3d12/D3D12_*_One.h
 src/render/direct3d12/D3D12_*_Series.h
+src/gpu/d3d12/D3D12_*_One.h
+src/gpu/d3d12/D3D12_*_Series.h
 Directory.Build.props
 
 # for Android
diff --git a/Android.mk b/Android.mk
index c26fc6721fe95..31bc23bc42be4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -35,6 +35,8 @@ LOCAL_SRC_FILES := \
 	$(wildcard $(LOCAL_PATH)/src/dynapi/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/events/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/file/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/gpu/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/gpu/vulkan/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 414904b4a114b..d69831ae64644 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -233,6 +233,7 @@ endmacro()
 
 define_sdl_subsystem(Audio)
 define_sdl_subsystem(Video)
+define_sdl_subsystem(Gpu DEPS SDL_VIDEO)
 define_sdl_subsystem(Render DEPS SDL_VIDEO)
 define_sdl_subsystem(Camera DEPS SDL_VIDEO)
 define_sdl_subsystem(Joystick)
@@ -331,6 +332,7 @@ dep_option(SDL_RENDER_D3D          "Enable the Direct3D 9 render driver" ON "SDL
 dep_option(SDL_RENDER_D3D11        "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
 dep_option(SDL_RENDER_D3D12        "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
 dep_option(SDL_RENDER_METAL        "Enable the Metal render driver" ON "SDL_RENDER;${APPLE}" OFF)
+set_option(SDL_RENDER_GPU          "Enable the SDL_Gpu render driver" ON)
 dep_option(SDL_VIVANTE             "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
 dep_option(SDL_VULKAN              "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF)
 dep_option(SDL_RENDER_VULKAN       "Enable the Vulkan render driver" ON "SDL_RENDER;SDL_VULKAN" OFF)
@@ -350,6 +352,7 @@ set_option(SDL_LIBUDEV             "Enable libudev support" ON)
 set_option(SDL_ASAN                "Use AddressSanitizer to detect memory errors" OFF)
 set_option(SDL_CCACHE              "Use Ccache to speed up build" OFF)
 set_option(SDL_CLANG_TIDY          "Run clang-tidy static analysis" OFF)
+set_option(SDL_GPU_DXVK            "Build SDL_Gpu with DXVK support" OFF)
 
 set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION")
 
@@ -1123,6 +1126,7 @@ sdl_glob_sources(
   "${SDL3_SOURCE_DIR}/src/events/*.c"
   "${SDL3_SOURCE_DIR}/src/file/*.c"
   "${SDL3_SOURCE_DIR}/src/filesystem/*.c"
+  "${SDL3_SOURCE_DIR}/src/gpu/*.c"
   "${SDL3_SOURCE_DIR}/src/joystick/*.c"
   "${SDL3_SOURCE_DIR}/src/haptic/*.c"
   "${SDL3_SOURCE_DIR}/src/hidapi/*.c"
@@ -1704,6 +1708,16 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
       )
     endif()
 
+    if(SDL_GPU AND SDL_GPU_DXVK)
+      if(PKG_CONFIG_FOUND)
+        pkg_search_module(DXVK_NATIVE dxvk-dxgi)
+        if(DXVK_NATIVE_FOUND)
+          set(HAVE_D3D11_H TRUE)
+          sdl_include_directories(PRIVATE SYSTEM ${DXVK_NATIVE_INCLUDE_DIRS})
+        endif()
+      endif()
+    endif()
+
     # Always compiled for Linux, unconditionally:
     sdl_sources(
       "${SDL3_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c"
@@ -2363,6 +2377,10 @@ elseif(APPLE)
           set(SDL_VIDEO_RENDER_METAL 1)
           set(HAVE_RENDER_METAL TRUE)
         endif()
+        if (SDL_GPU)
+          set(SDL_GPU_METAL 1)
+          sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/metal/*.m")
+        endif()
       endif()
     endif()
   endif()
@@ -2925,6 +2943,27 @@ if(SDL_VIDEO)
   endif()
 endif()
 
+if(SDL_GPU)
+  if(HAVE_D3D11_H)
+    sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/d3d11/*.c")
+    set(SDL_GPU_D3D11 1)
+    set(HAVE_SDL_GPU TRUE)
+  endif()
+  if(SDL_RENDER_D3D12)
+    sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/d3d12/*.c")
+    set(SDL_GPU_D3D12 1)
+    set(HAVE_SDL_GPU TRUE)
+  endif()
+  if(SDL_VIDEO_VULKAN)
+    sdl_glob_sources("${SDL3_SOURCE_DIR}/src/gpu/vulkan/*.c")
+    set(SDL_GPU_VULKAN 1)
+    set(HAVE_SDL_GPU TRUE)
+  endif()
+  if(SDL_RENDER_GPU)
+    set(SDL_VIDEO_RENDER_GPU 1)
+  endif()
+endif()
+
 # Dummies
 # configure.ac does it differently:
 # if not have X
diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 1ac0e2ec30534..fa470003ceb66 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -166,6 +166,7 @@
     </Link>
     <PreBuildEvent>
       <Command>$(SolutionDir)..\src\render\direct3d12\compile_shaders_xbox.bat $(SolutionDir)</Command>
+      <Command>$(SolutionDir)..\src\gpu\d3d12\compile_shaders_xbox.bat $(SolutionDir)</Command>
     </PreBuildEvent>
     <PreBuildEvent>
       <Message>Building shader blobs (Xbox Series)</Message>
@@ -200,6 +201,7 @@
     </Link>
     <PreBuildEvent>
       <Command>$(SolutionDir)..\src\render\direct3d12\compile_shaders_xbox.bat $(SolutionDir) one</Command>
+      <Command>$(SolutionDir)..\src\gpu\d3d12\compile_shaders_xbox.bat $(SolutionDir) one</Command>
     </PreBuildEvent>
     <PreBuildEvent>
       <Message>Building shader blobs (Xbox One)</Message>
@@ -266,6 +268,7 @@
     </Link>
     <PreBuildEvent>
       <Command>$(SolutionDir)..\src\render\direct3d12\compile_shaders_xbox.bat $(SolutionDir)</Command>
+      <Command>$(SolutionDir)..\src\gpu\d3d12\compile_shaders_xbox.bat $(SolutionDir)</Command>
     </PreBuildEvent>
     <PreBuildEvent>
       <Message>Building shader blobs (Xbox Series)</Message>
@@ -301,6 +304,7 @@
     </Link>
     <PreBuildEvent>
       <Command>$(SolutionDir)..\src\render\direct3d12\compile_shaders_xbox.bat $(SolutionDir) one</Command>
+      <Command>$(SolutionDir)..\src\gpu\d3d12\compile_shaders_xbox.bat $(SolutionDir) one</Command>
     </PreBuildEvent>
     <PreBuildEvent>
       <Message>Building shader blobs (Xbox One)</Message>
@@ -330,6 +334,7 @@
     <ClInclude Include="..\..\include\SDL3\SDL_events.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_filesystem.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_gamepad.h" />
+    <ClInclude Include="..\..\include\SDL3\SDL_gpu.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_guid.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_haptic.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_hints.h" />
@@ -424,6 +429,7 @@
     <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
     <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
     <ClInclude Include="..\..\src\filesystem\SDL_sysfilesystem.h" />
+    <ClInclude Include="..\..\src\gpu\SDL_sysgpu.h" />
     <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
     <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
     <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
@@ -865,6 +871,15 @@
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb_lsx.c" />
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb_sse.c" />
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb_std.c" />
+    <ClCompile Include="..\..\src\gpu\SDL_gpu.c" />
+    <ClCompile Include="..\..\src\gpu\d3d11\SDL_gpu_d3d11.c" />
+    <ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c">
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.Scarlett.x64'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.Scarlett.x64'">CompileAsCpp</CompileAs>
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">CompileAsCpp</CompileAs>
+    </ClCompile>
+    <ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\core\windows\version.rc" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index fbd091f59066e..61caf6d2492eb 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -57,6 +57,10 @@
     <ClCompile Include="..\..\src\events\SDL_windowevents.c" />
     <ClCompile Include="..\..\src\file\SDL_iostream.c" />
     <ClCompile Include="..\..\src\filesystem\gdk\SDL_sysfilesystem.cpp" />
+    <ClCompile Include="..\..\src\gpu\SDL_gpu.c" />
+    <ClCompile Include="..\..\src\gpu\d3d11\SDL_gpu_d3d11.c" />
+    <ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c" />
+    <ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
     <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
     <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
@@ -249,6 +253,7 @@
     <ClInclude Include="..\..\include\SDL3\SDL_events.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_filesystem.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_gamepad.h" />
+    <ClInclude Include="..\..\include\SDL3\SDL_gpu.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_guid.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_haptic.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_hints.h" />
@@ -341,6 +346,7 @@
     <ClInclude Include="..\..\src\filesystem\SDL_sysfilesystem.h">
       <Filter>filesystem</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\gpu\SDL_sysgpu.h" />
     <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
     <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
     <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj
index 1c7b029a1db05..a7147715000e3 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj
+++ b/VisualC-WinRT/SDL-UWP.vcxproj
@@ -125,6 +125,7 @@
     <ClInclude Include="..\src\events\SDL_touch_c.h" />
     <ClInclude Include="..\src\events\SDL_windowevents_c.h" />
     <ClInclude Include="..\src\filesystem\SDL_sysfilesystem.h" />
+    <ClInclude Include="..\src\gpu\SDL_sysgpu.h" />
     <ClInclude Include="..\src\haptic\SDL_haptic_c.h" />
     <ClInclude Include="..\src\haptic\SDL_syshaptic.h" />
     <ClInclude Include="..\src\haptic\windows\SDL_dinputhaptic_c.h" />
@@ -343,6 +344,9 @@
     <ClCompile Include="..\src\file\SDL_iostream.c" />
     <ClCompile Include="..\src\filesystem\SDL_filesystem.c" />
     <ClCompile Include="..\src\filesystem\windows\SDL_sysfsops.c" />
+    <ClCompile Include="..\src\gpu\SDL_gpu.c "/>
+    <ClCompile Include="..\src\gpu\d3d11\SDL_gpu_d3d11.c "/>
+    <ClCompile Include="..\src\gpu\d3d12\SDL_gpu_d3d12.c "/>
     <ClCompile Include="..\src\haptic\dummy\SDL_syshaptic.c" />
     <ClCompile Include="..\src\haptic\SDL_haptic.c" />
     <ClCompile Include="..\src\haptic\windows\SDL_dinputhaptic.c" />
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index 657afb9f2e1eb..e1cbf90bf592d 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -254,6 +254,7 @@
     <ClInclude Include="..\..\include\SDL3\SDL_events.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_filesystem.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_gamepad.h" />
+    <ClInclude Include="..\..\include\SDL3\SDL_gpu.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_guid.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_haptic.h" />
     <ClInclude Include="..\..\include\SDL3\SDL_hints.h" />
@@ -348,6 +349,8 @@
     <ClInclude Include="..\..\src\events\SDL_touch_c.h" />
     <ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
     <ClInclude Include="..\..\src\filesystem\SDL_sysfilesystem.h" />
+    <ClInclude Include="..\..\src\gpu\SDL_sysgpu.h" />
+    <ClInclude Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan_vkfuncs.h" />
     <ClInclude Include="..\..\src\haptic\SDL_haptic_c.h" />
     <ClInclude Include="..\..\src\haptic\SDL_syshaptic.h" />
     <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
@@ -408,6 +411,10 @@
     <ClCompile Include="..\..\src\dialog\SDL_dialog_utils.c" />
     <ClCompile Include="..\..\src\filesystem\SDL_filesystem.c" />
     <ClCompile Include="..\..\src\filesystem\windows\SDL_sysfsops.c" />
+    <ClCompile Include="..\..\src\gpu\SDL_gpu.c" />
+    <ClCompile Include="..\..\src\gpu\d3d11\SDL_gpu_d3d11.c" />
+    <ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c" />
+    <ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c" />
     <ClCompile Include="..\..\src\main\generic\SDL_sysmain_callbacks.c" />
     <ClCompile Include="..\..\src\main\SDL_main_callbacks.c" />
     <ClCompile Include="..\..\src\main\SDL_runapp.c" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 57b5a527a7050..f7794e85666c6 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -198,6 +198,8 @@
     </Filter>
     <Filter Include="time\windows">
       <UniqueIdentifier>{0000d7fda065b13b0ca4ab262c380000}</UniqueIdentifier>
+    <Filter Include="gpu">
+      <UniqueIdentifier>{098fbef9-d8a0-4b3b-b57b-d157d395335d}</UniqueIdentifier>
     </Filter>
     <Filter Include="dialog">
       <UniqueIdentifier>{00008dfdfa0190856fbf3c7db52d0000}</UniqueIdentifier>
@@ -907,6 +909,14 @@
     </ClInclude>
     <ClInclude Include="..\..\src\video\offscreen\SDL_offscreenwindow.h">
       <Filter>video\offscreen</Filter>
+    <ClInclude Include="..\..\include\SDL3\SDL_gpu.h">
+      <Filter>API Headers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\gpu\SDL_sysgpu.h">
+      <Filter>gpu</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan_vkfuncs.h">
+      <Filter>gpu</Filter>
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
@@ -1562,6 +1572,18 @@
     <ClCompile Include="..\..\src\video\offscreen\SDL_offscreenwindow.c">
       <Filter>video\offscreen</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\gpu\SDL_gpu.c">
+      <Filter>gpu</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\gpu\d3d11\SDL_gpu_d3d11.c">
+      <Filter>gpu</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\gpu\d3d12\SDL_gpu_d3d12.c">
+      <Filter>gpu</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\gpu\vulkan\SDL_gpu_vulkan.c">
+      <Filter>gpu</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\core\windows\version.rc" />
diff --git a/include/SDL3/SDL.h b/include/SDL3/SDL.h
index 4e18f638224be..c9633941dcc5a 100644
--- a/include/SDL3/SDL.h
+++ b/include/SDL3/SDL.h
@@ -43,6 +43,7 @@
 #include <SDL3/SDL_events.h>
 #include <SDL3/SDL_filesystem.h>
 #include <SDL3/SDL_gamepad.h>
+#include <SDL3/SDL_gpu.h>
 #include <SDL3/SDL_guid.h>
 #include <SDL3/SDL_haptic.h>
 #include <SDL3/SDL_hidapi.h>
diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h
new file mode 100644
index 0000000000000..3ac74d63ca518
--- /dev/null
+++ b/include/SDL3/SDL_gpu.h
@@ -0,0 +1,2512 @@
+/*
+  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.
+*/
+
+/**
+ * \file SDL_gpu.h
+ *
+ * Include file for SDL GPU API functions
+ */
+
+#ifndef SDL_GPU_H
+#define SDL_GPU_H
+
+#include <SDL3/SDL_stdinc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Type Declarations */
+
+typedef struct SDL_GpuDevice SDL_GpuDevice;
+typedef struct SDL_GpuBuffer SDL_GpuBuffer;
+typedef struct SDL_GpuTransferBuffer SDL_GpuTransferBuffer;
+typedef struct SDL_GpuTexture SDL_GpuTexture;
+typedef struct SDL_GpuSampler SDL_GpuSampler;
+typedef struct SDL_GpuShader SDL_GpuShader;
+typedef struct SDL_GpuComputePipeline SDL_GpuComputePipeline;
+typedef struct SDL_GpuGraphicsPipeline SDL_GpuGraphicsPipeline;
+typedef struct SDL_GpuCommandBuffer SDL_GpuCommandBuffer;
+typedef struct SDL_GpuRenderPass SDL_GpuRenderPass;
+typedef struct SDL_GpuComputePass SDL_GpuComputePass;
+typedef struct SDL_GpuCopyPass SDL_GpuCopyPass;
+typedef struct SDL_GpuFence SDL_GpuFence;
+
+typedef enum SDL_GpuPrimitiveType
+{
+    SDL_GPU_PRIMITIVETYPE_POINTLIST,
+    SDL_GPU_PRIMITIVETYPE_LINELIST,
+    SDL_GPU_PRIMITIVETYPE_LINESTRIP,
+    SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
+    SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP
+} SDL_GpuPrimitiveType;
+
+typedef enum SDL_GpuLoadOp
+{
+    SDL_GPU_LOADOP_LOAD,
+    SDL_GPU_LOADOP_CLEAR,
+    SDL_GPU_LOADOP_DONT_CARE
+} SDL_GpuLoadOp;
+
+typedef enum SDL_GpuStoreOp
+{
+    SDL_GPU_STOREOP_STORE,
+    SDL_GPU_STOREOP_DONT_CARE
+} SDL_GpuStoreOp;
+
+typedef enum SDL_GpuIndexElementSize
+{
+    SDL_GPU_INDEXELEMENTSIZE_16BIT,
+    SDL_GPU_INDEXELEMENTSIZE_32BIT
+} SDL_GpuIndexElementSize;
+
+/* Texture format support varies depending on driver, hardware, and usage flags.
+ * In general, you should use SDL_SupportsGpuTextureFormat to query if a format
+ * is supported before using it. However, there are a few guaranteed formats.
+ *
+ * For SAMPLER usage, the following formats are universally supported:
+ *  - R8G8B8A8_UNORM
+ *  - B8G8R8A8_UNORM
+ *  - R8_UNORM
+ *  - R8G8_SNORM
+ *  - R8G8B8A8_SNORM
+ *  - R16_FLOAT
+ *  - R16G16_FLOAT
+ *  - R16G16B16A16_FLOAT
+ *  - R32_FLOAT
+ *  - R32G32_FLOAT
+ *  - R32G32B32A32_FLOAT
+ *  - R8G8B8A8_UNORM_SRGB
+ *  - B8G8R8A8_UNORM_SRGB
+ *  - D16_UNORM
+ *
+ * For COLOR_TARGET usage, the following formats are universally supported:
+ *  - R8G8B8A8_UNORM
+ *  - B8G8R8A8_UNORM
+ *  - R8_UNORM
+ *  - R16_FLOAT
+ *  - R16G16_FLOAT
+ *  - R16G16B16A16_FLOAT
+ *  - R32_FLOAT
+ *  - R32G32_FLOAT
+ *  - R32G32B32A32_FLOAT
+ *  - R8_UINT
+ *  - R8G8_UINT
+ *  - R8G8B8A8_UINT
+ *  - R16_UINT
+ *  - R16G16_UINT
+ *  - R16G16B16A16_UINT
+ *  - R8G8B8A8_UNORM_SRGB
+ *  - B8G8R8A8_UNORM_SRGB
+ *
+ * For STORAGE usages, the following formats are universally supported:
+ *  - R8G8B8A8_UNORM
+ *  - R8G8B8A8_SNORM
+ *  - R16G16B16A16_FLOAT
+ *  - R32_FLOAT
+ *  - R32G32_FLOAT
+ *  - R32G32B32A32_FLOAT
+ *  - R8_UINT
+ *  - R8G8_UINT
+ *  - R8G8B8A8_UINT
+ *  - R16_UINT
+ *  - R16G16_UINT
+ *  - R16G16B16A16_UINT
+ *
+ * For DEPTH_STENCIL_TARGET usage, the following formats are universally supported:
+ *  - D16_UNORM
+ *  - Either (but not necessarily both!) D24_UNORM or D32_SFLOAT
+ *  - Either (but not necessarily both!) D24_UNORM_S8_UINT or D32_SFLOAT_S8_UINT
+ *
+ * Unless D16_UNORM is sufficient for your purposes, always check which
+ * of D24/D32 is supported before creating a depth-stencil texture!
+ */
+typedef enum SDL_GpuTextureFormat
+{
+    SDL_GPU_TEXTUREFORMAT_INVALID = -1,
+
+    /* Unsigned Normalized Float Color Formats */
+    SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
+    SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM,
+    SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM,
+    SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM,
+    SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM,
+    SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM,
+    SDL_GPU_TEXTUREFORMAT_R16G16_UNORM,
+    SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM,
+    SDL_GPU_TEXTUREFORMAT_R8_UNORM,
+    SDL_GPU_TEXTUREFORMAT_A8_UNORM,
+    /* Compressed Unsigned Normalized Float Color Formats */
+    SDL_GPU_TEXTUREFORMAT_BC1_UNORM,
+    SDL_GPU_TEXTUREFORMAT_BC2_UNORM,
+    SDL_GPU_TEXTUREFORMAT_BC3_UNORM,
+    SDL_GPU_TEXTUREFORMAT_BC7_UNORM,
+    /* Signed Normalized Float Color Formats  */
+    SDL_GPU_TEXTUREFORMAT_R8G8_SNORM,
+    SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM,
+    /* Signed Float Color Formats */
+    SDL_GPU_TEXTUREFORMAT_R16_FLOAT,
+    SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT,
+    SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT,
+    SDL_GPU_TEXTUREFORMAT_R32_FLOAT,
+    SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT,
+    SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT,
+    /* Unsigned Integer Color Formats */
+    SDL_GPU_TEXTUREFORMAT_R8_UINT,
+    SDL_GPU_TEXTUREFORMAT_R8G8_UINT,
+    SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT,
+    SDL_GPU_TEXTUREFORMAT_R16_UINT,
+    SDL_GPU_TEXTUREFORMAT_R16G16_UINT,
+    SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT,
+    /* SRGB Unsigned Normalized Color Formats */
+    SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB,
+    SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB,
+    /* Compressed SRGB Unsign

(Patch may be truncated, please check the link at the top of this post.)