SDL: Added support for floating point texture formats

From 7561116873d99e6a566c6cdabd343090f7553c9d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 1 Feb 2024 11:22:04 -0800
Subject: [PATCH] Added support for floating point texture formats

---
 src/render/SDL_render.c                  | 20 +++++++++++++++++---
 src/render/direct3d11/SDL_render_d3d11.c |  7 ++++++-
 src/render/direct3d12/SDL_render_d3d12.c |  7 ++++++-
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index e0c0a1cc26d5..97cd7464e77a 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -1383,6 +1383,17 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
         }
     }
 
+    /* Look for floating point pixel formats if needed */
+    if (format == SDL_PIXELFORMAT_UNKNOWN &&
+        (SDL_ISPIXELFORMAT_10BIT(fmt->format) || SDL_ISPIXELFORMAT_FLOAT(fmt->format))) {
+        for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) {
+            if (SDL_ISPIXELFORMAT_FLOAT(renderer->info.texture_formats[i])) {
+                format = renderer->info.texture_formats[i];
+                break;
+            }
+        }
+    }
+
     /* Fallback, choose a valid pixel format */
     if (format == SDL_PIXELFORMAT_UNKNOWN) {
         format = renderer->info.texture_formats[0];
@@ -1410,9 +1421,12 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
     }
 
     if ((SDL_COLORSPACETRANSFER(colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ && !SDL_ISPIXELFORMAT_10BIT(format)) ||
-        (colorspace == SDL_COLORSPACE_SCRGB && !SDL_ISPIXELFORMAT_FLOAT(format))) {
-        /* Need to do SDR conversion */
-        colorspace = SDL_COLORSPACE_SRGB;
+        colorspace == SDL_COLORSPACE_SCRGB) {
+        if (SDL_ISPIXELFORMAT_FLOAT(format)) {
+            colorspace = SDL_COLORSPACE_SCRGB;
+        } else {
+            colorspace = SDL_COLORSPACE_SRGB;
+        }
     }
 
     props = SDL_CreateProperties();
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index 58df1a235323..c5f103835e29 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -217,6 +217,8 @@ Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat)
 static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
 {
     switch (format) {
+    case SDL_PIXELFORMAT_RGBA64_FLOAT:
+        return DXGI_FORMAT_R16G16B16A16_FLOAT;
     case SDL_PIXELFORMAT_ARGB8888:
         if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
             return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
@@ -241,6 +243,8 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 color
 static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
 {
     switch (format) {
+    case SDL_PIXELFORMAT_RGBA64_FLOAT:
+        return DXGI_FORMAT_R16G16B16A16_FLOAT;
     case SDL_PIXELFORMAT_ARGB8888:
         if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
             return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
@@ -2603,10 +2607,11 @@ SDL_RenderDriver D3D11_RenderDriver = {
         "direct3d11",
         (SDL_RENDERER_ACCELERATED |
          SDL_RENDERER_PRESENTVSYNC), /* flags.  see SDL_RendererFlags */
-        6,                           /* num_texture_formats */
+        7,                           /* num_texture_formats */
         {                            /* texture_formats */
           SDL_PIXELFORMAT_ARGB8888,
           SDL_PIXELFORMAT_XRGB8888,
+          SDL_PIXELFORMAT_RGBA64_FLOAT,
           SDL_PIXELFORMAT_YV12,
           SDL_PIXELFORMAT_IYUV,
           SDL_PIXELFORMAT_NV12,
diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 44470f0ea033..bfd5da1abf90 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -291,6 +291,8 @@ Uint32 D3D12_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat)
 static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
 {
     switch (format) {
+    case SDL_PIXELFORMAT_RGBA64_FLOAT:
+        return DXGI_FORMAT_R16G16B16A16_FLOAT;
     case SDL_PIXELFORMAT_ARGB8888:
         if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
             return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
@@ -315,6 +317,8 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 color
 static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
 {
     switch (format) {
+    case SDL_PIXELFORMAT_RGBA64_FLOAT:
+        return DXGI_FORMAT_R16G16B16A16_FLOAT;
     case SDL_PIXELFORMAT_ARGB8888:
         if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
             return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
@@ -3113,10 +3117,11 @@ SDL_RenderDriver D3D12_RenderDriver = {
         "direct3d12",
         (SDL_RENDERER_ACCELERATED |
          SDL_RENDERER_PRESENTVSYNC), /* flags.  see SDL_RendererFlags */
-        6,                           /* num_texture_formats */
+        7,                           /* num_texture_formats */
         {                            /* texture_formats */
           SDL_PIXELFORMAT_ARGB8888,
           SDL_PIXELFORMAT_XRGB8888,
+          SDL_PIXELFORMAT_RGBA64_FLOAT,
           SDL_PIXELFORMAT_YV12,
           SDL_PIXELFORMAT_IYUV,
           SDL_PIXELFORMAT_NV12,