Browse Source

GPU: Cube Arrays (#10800)

---------

Co-authored-by: Caleb Cornett <[email protected]>
Evan Hemsley 11 months ago
parent
commit
66489f91bb

+ 5 - 4
include/SDL3/SDL_gpu.h

@@ -484,10 +484,11 @@ typedef Uint32 SDL_GPUTextureUsageFlags;
  */
 typedef enum SDL_GPUTextureType
 {
-    SDL_GPU_TEXTURETYPE_2D,        /**< The texture is a 2-dimensional image. */
-    SDL_GPU_TEXTURETYPE_2D_ARRAY,  /**< The texture is a 2-dimensional array image. */
-    SDL_GPU_TEXTURETYPE_3D,        /**< The texture is a 3-dimensional image. */
-    SDL_GPU_TEXTURETYPE_CUBE       /**< The texture is a cube image. */
+    SDL_GPU_TEXTURETYPE_2D,         /**< The texture is a 2-dimensional image. */
+    SDL_GPU_TEXTURETYPE_2D_ARRAY,   /**< The texture is a 2-dimensional array image. */
+    SDL_GPU_TEXTURETYPE_3D,         /**< The texture is a 3-dimensional image. */
+    SDL_GPU_TEXTURETYPE_CUBE,       /**< The texture is a cube image. */
+	SDL_GPU_TEXTURETYPE_CUBE_ARRAY  /**< The texture is a cube array image. */
 } SDL_GPUTextureType;
 
 /**

+ 28 - 1
src/gpu/SDL_gpu.c

@@ -177,6 +177,7 @@ SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline(
     SDL_GPUShader *blit_from_2d_array_shader,
     SDL_GPUShader *blit_from_3d_shader,
     SDL_GPUShader *blit_from_cube_shader,
+    SDL_GPUShader *blit_from_cube_array_shader,
     BlitPipelineCacheEntry **blit_pipelines,
     Uint32 *blit_pipeline_count,
     Uint32 *blit_pipeline_capacity)
@@ -211,7 +212,9 @@ SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline(
     blit_pipeline_create_info.vertex_shader = blit_vertex_shader;
     if (source_texture_type == SDL_GPU_TEXTURETYPE_CUBE) {
         blit_pipeline_create_info.fragment_shader = blit_from_cube_shader;
-    } else if (source_texture_type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
+    } else if (source_texture_type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
+        blit_pipeline_create_info.fragment_shader = blit_from_cube_array_shader;
+    }  else if (source_texture_type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
         blit_pipeline_create_info.fragment_shader = blit_from_2d_array_shader;
     } else if (source_texture_type == SDL_GPU_TEXTURETYPE_3D) {
         blit_pipeline_create_info.fragment_shader = blit_from_3d_shader;
@@ -259,6 +262,7 @@ void SDL_GPU_BlitCommon(
     SDL_GPUShader *blit_from_2d_array_shader,
     SDL_GPUShader *blit_from_3d_shader,
     SDL_GPUShader *blit_from_cube_shader,
+    SDL_GPUShader *blit_from_cube_array_shader,
     BlitPipelineCacheEntry **blit_pipelines,
     Uint32 *blit_pipeline_count,
     Uint32 *blit_pipeline_capacity)
@@ -283,6 +287,7 @@ void SDL_GPU_BlitCommon(
         blit_from_2d_array_shader,
         blit_from_3d_shader,
         blit_from_cube_shader,
+        blit_from_cube_array_shader,
         blit_pipelines,
         blit_pipeline_count,
         blit_pipeline_capacity);
@@ -818,6 +823,28 @@ SDL_GPUTexture *SDL_CreateGPUTexture(
                 SDL_assert_release(!"For cube textures: the format is unsupported for the given usage");
                 failed = true;
             }
+        } else if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
+            // Cubemap array validation
+            if (createinfo->width != createinfo->height) {
+                SDL_assert_release(!"For cube array textures: width and height must be identical");
+                failed = true;
+            }
+            if (createinfo->width > MAX_2D_DIMENSION || createinfo->height > MAX_2D_DIMENSION) {
+                SDL_assert_release(!"For cube array textures: width and height must be <= 16384");
+                failed = true;
+            }
+            if (createinfo->layer_count_or_depth % 6 != 0) {
+                SDL_assert_release(!"For cube array textures: layer_count_or_depth must be a multiple of 6");
+                failed = true;
+            }
+            if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) {
+                SDL_assert_release(!"For cube array textures: sample_count must be SDL_GPU_SAMPLECOUNT_1");
+                failed = true;
+            }
+            if (!SDL_GPUTextureSupportsFormat(device, createinfo->format, SDL_GPU_TEXTURETYPE_CUBE_ARRAY, createinfo->usage)) {
+                SDL_assert_release(!"For cube array textures: the format is unsupported for the given usage");
+                failed = true;
+            }
         } else if (createinfo->type == SDL_GPU_TEXTURETYPE_3D) {
             // 3D Texture Validation
             if (createinfo->width > MAX_3D_DIMENSION || createinfo->height > MAX_3D_DIMENSION || createinfo->layer_count_or_depth > MAX_3D_DIMENSION) {

+ 2 - 0
src/gpu/SDL_sysgpu.h

@@ -262,6 +262,7 @@ SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline(
     SDL_GPUShader *blitFrom2DArrayShader,
     SDL_GPUShader *blitFrom3DShader,
     SDL_GPUShader *blitFromCubeShader,
+    SDL_GPUShader *blitFromCubeArrayShader,
     BlitPipelineCacheEntry **blitPipelines,
     Uint32 *blitPipelineCount,
     Uint32 *blitPipelineCapacity);
@@ -276,6 +277,7 @@ void SDL_GPU_BlitCommon(
     SDL_GPUShader *blitFrom2DArrayShader,
     SDL_GPUShader *blitFrom3DShader,
     SDL_GPUShader *blitFromCubeShader,
+    SDL_GPUShader *blitFromCubeArrayShader,
     BlitPipelineCacheEntry **blitPipelines,
     Uint32 *blitPipelineCount,
     Uint32 *blitPipelineCapacity);

+ 387 - 8
src/gpu/d3d11/D3D11_Blit.h

@@ -1014,10 +1014,10 @@ switch r1.x
   break 
   case l(2)
   mul r0.xz, r0.xxzx, l(1.000000, 0.000000, -1.000000, 0.000000)
-  mov r0.y, l(-1.000000)
+  mov r0.y, l(1.000000)
   break 
   case l(3)
-  mov r0.y, l(1.000000)
+  mov r0.y, l(-1.000000)
   break 
   case l(4)
   mul r0.xy, r0.xzxx, l(1.000000, -1.000000, 0.000000, 0.000000)
@@ -1039,10 +1039,10 @@ ret
 
 const BYTE g_BlitFromCube[] =
 {
-     68,  88,  66,  67,  74, 191, 
-     49,  23, 175,  39, 209, 200, 
-     62, 140,  77, 177,  73, 191, 
-     60, 231,   1,   0,   0,   0, 
+     68,  88,  66,  67,  10, 119, 
+    223,  12, 113, 233, 111,  65, 
+     57, 156,   6,  26, 212, 111, 
+     79,  35,   1,   0,   0,   0, 
     176,   6,   0,   0,   5,   0, 
       0,   0,  52,   0,   0,   0, 
     156,   2,   0,   0, 244,   2, 
@@ -1248,13 +1248,13 @@ const BYTE g_BlitFromCube[] =
      54,   0,   0,   5,  34,   0, 
      16,   0,   0,   0,   0,   0, 
       1,  64,   0,   0,   0,   0, 
-    128, 191,   2,   0,   0,   1, 
+    128,  63,   2,   0,   0,   1, 
       6,   0,   0,   3,   1,  64, 
       0,   0,   3,   0,   0,   0, 
      54,   0,   0,   5,  34,   0, 
      16,   0,   0,   0,   0,   0, 
       1,  64,   0,   0,   0,   0, 
-    128,  63,   2,   0,   0,   1, 
+    128, 191,   2,   0,   0,   1, 
       6,   0,   0,   3,   1,  64, 
       0,   0,   4,   0,   0,   0, 
      56,   0,   0,  10,  50,   0, 
@@ -1326,3 +1326,382 @@ const BYTE g_BlitFromCube[] =
       0,   0,   0,   0,   0,   0, 
       0,   0
 };
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer SourceRegionBuffer
+// {
+//
+//   float2 UVLeftTop;                  // Offset:    0 Size:     8
+//   float2 UVDimensions;               // Offset:    8 Size:     8
+//   uint MipLevel;                     // Offset:   16 Size:     4
+//   float LayerOrDepth;                // Offset:   20 Size:     4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// SourceSampler                     sampler      NA          NA             s0      1 
+// SourceTextureCubeArray            texture  float4   cubearray             t0      1 
+// SourceRegionBuffer                cbuffer      NA          NA            cb0      1 
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// TEXCOORD                 0   xy          0     NONE   float   xy  
+// SV_POSITION              0   xyzw        1      POS   float       
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+ps_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texturecubearray (float,float,float,float) t0
+dcl_input_ps linear v0.xy
+dcl_output o0.xyzw
+dcl_temps 3
+mad r0.xy, cb0[0].zwzz, v0.xyxx, cb0[0].xyxx
+mad r0.xz, r0.xxyx, l(2.000000, 0.000000, 2.000000, 0.000000), l(-1.000000, 0.000000, -1.000000, 0.000000)
+ftou r1.x, cb0[1].y
+udiv r1.x, r2.x, r1.x, l(6)
+switch r2.x
+  case l(0)
+  mov r0.yz, -r0.zzxz
+  mov r0.x, l(1.000000)
+  break 
+  case l(1)
+  mov r0.y, l(-1.000000)
+  mov r0.w, -r0.z
+  mov r0.xyz, r0.ywxy
+  break 
+  case l(2)
+  mul r0.xz, r0.xxzx, l(1.000000, 0.000000, -1.000000, 0.000000)
+  mov r0.y, l(1.000000)
+  break 
+  case l(3)
+  mov r0.y, l(-1.000000)
+  break 
+  case l(4)
+  mul r0.xy, r0.xzxx, l(1.000000, -1.000000, 0.000000, 0.000000)
+  mov r0.z, l(1.000000)
+  break 
+  case l(5)
+  mov r0.xy, -r0.xzxx
+  mov r0.z, l(-1.000000)
+  break 
+endswitch 
+utof r0.w, r1.x
+utof r1.x, cb0[1].x
+sample_l_indexable(texturecubearray)(float,float,float,float) o0.xyzw, r0.xyzw, t0.xyzw, s0, r1.x
+ret 
+// Approximately 34 instruction slots used
+#endif
+
+const BYTE g_BlitFromCubeArray[] =
+{
+     68,  88,  66,  67,  59, 147, 
+    203,  21,  33, 208, 116, 167, 
+     11, 254, 103,  46, 206, 206, 
+    176,  66,   1,   0,   0,   0, 
+    196,   6,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    160,   2,   0,   0, 248,   2, 
+      0,   0,  44,   3,   0,   0, 
+     40,   6,   0,   0,  82,  68, 
+     69,  70, 100,   2,   0,   0, 
+      1,   0,   0,   0, 212,   0, 
+      0,   0,   3,   0,   0,   0, 
+     60,   0,   0,   0,   0,   5, 
+    255, 255,   0,   1,   0,   0, 
+     60,   2,   0,   0,  82,  68, 
+     49,  49,  60,   0,   0,   0, 
+     24,   0,   0,   0,  32,   0, 
+      0,   0,  40,   0,   0,   0, 
+     36,   0,   0,   0,  12,   0, 
+      0,   0,   0,   0,   0,   0, 
+    156,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 170,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,  10,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     13,   0,   0,   0, 193,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+     83, 111, 117, 114,  99, 101, 
+     83,  97, 109, 112, 108, 101, 
+    114,   0,  83, 111, 117, 114, 
+     99, 101,  84, 101, 120, 116, 
+    117, 114, 101,  67, 117,  98, 
+    101,  65, 114, 114,  97, 121, 
+      0,  83, 111, 117, 114,  99, 
+    101,  82, 101, 103, 105, 111, 
+    110,  66, 117, 102, 102, 101, 
+    114,   0, 193,   0,   0,   0, 
+      4,   0,   0,   0, 236,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 140,   1,   0,   0, 
+      0,   0,   0,   0,   8,   0, 
+      0,   0,   2,   0,   0,   0, 
+    160,   1,   0,   0,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+    196,   1,   0,   0,   8,   0, 
+      0,   0,   8,   0,   0,   0, 
+      2,   0,   0,   0, 160,   1, 
+      0,   0,   0,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0, 209,   1, 
+      0,   0,  16,   0,   0,   0, 
+      4,   0,   0,   0,   2,   0, 
+      0,   0, 224,   1,   0,   0, 
+      0,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   4,   2,   0,   0, 
+     20,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+     24,   2,   0,   0,   0,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+     85,  86,  76, 101, 102, 116, 
+     84, 111, 112,   0, 102, 108, 
+    111,  97, 116,  50,   0, 171, 
+    171, 171,   1,   0,   3,   0, 
+      1,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 150,   1, 
+      0,   0,  85,  86,  68, 105, 
+    109, 101, 110, 115, 105, 111, 
+    110, 115,   0,  77, 105, 112, 
+     76, 101, 118, 101, 108,   0, 
+    100, 119, 111, 114, 100,   0, 
+      0,   0,  19,   0,   1,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 218,   1,   0,   0, 
+     76,  97, 121, 101, 114,  79, 
+    114,  68, 101, 112, 116, 104, 
+      0, 102, 108, 111,  97, 116, 
+      0, 171,   0,   0,   3,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  17,   2, 
+      0,   0,  77, 105,  99, 114, 
+    111, 115, 111, 102, 116,  32, 
+     40,  82,  41,  32,  72,  76, 
+     83,  76,  32,  83, 104,  97, 
+    100, 101, 114,  32,  67, 111, 
+    109, 112, 105, 108, 101, 114, 
+     32,  49,  48,  46,  49,   0, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   3,   0,   0,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     15,   0,   0,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0,  83,  86,  95,  80,  79, 
+     83,  73,  84,  73,  79,  78, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171,  83,  72,  69,  88, 
+    244,   2,   0,   0,  80,   0, 
+      0,   0, 189,   0,   0,   0, 
+    106,   8,   0,   1,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  80,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   0,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   3,   0, 
+      0,   0,  50,   0,   0,  11, 
+     50,   0,  16,   0,   0,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      0,   0,   0,   0,  70, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  50,   0, 
+      0,  15,  82,   0,  16,   0, 
+      0,   0,   0,   0,   6,   1, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,  64,   0,   0,   0,   0, 
+      0,   0,   0,  64,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0, 128, 191,   0,   0, 
+      0,   0,   0,   0, 128, 191, 
+      0,   0,   0,   0,  28,   0, 
+      0,   6,  18,   0,  16,   0, 
+      1,   0,   0,   0,  26, 128, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  78,   0, 
+      0,   9,  18,   0,  16,   0, 
+      1,   0,   0,   0,  18,   0, 
+     16,   0,   2,   0,   0,   0, 
+     10,   0,  16,   0,   1,   0, 
+      0,   0,   1,  64,   0,   0, 
+      6,   0,   0,   0,  76,   0, 
+      0,   3,  10,   0,  16,   0, 
+      2,   0,   0,   0,   6,   0, 
+      0,   3,   1,  64,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6,  98,   0,  16,   0, 
+      0,   0,   0,   0, 166,   8, 
+     16, 128,  65,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  18,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+      2,   0,   0,   1,   6,   0, 
+      0,   3,   1,  64,   0,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5,  34,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128, 191, 
+     54,   0,   0,   6, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+     42,   0,  16, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 114,   0, 
+     16,   0,   0,   0,   0,   0, 
+    214,   4,  16,   0,   0,   0, 
+      0,   0,   2,   0,   0,   1, 
+      6,   0,   0,   3,   1,  64, 
+      0,   0,   2,   0,   0,   0, 
+     56,   0,   0,  10,  82,   0, 
+     16,   0,   0,   0,   0,   0, 
+      6,   2,  16,   0,   0,   0, 
+      0,   0,   2,  64,   0,   0, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0, 128, 191, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  34,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+      2,   0,   0,   1,   6,   0, 
+      0,   3,   1,  64,   0,   0, 
+      3,   0,   0,   0,  54,   0, 
+      0,   5,  34,   0,  16,   0, 
+      0,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128, 191, 
+      2,   0,   0,   1,   6,   0, 
+      0,   3,   1,  64,   0,   0, 
+      4,   0,   0,   0,  56,   0, 
+      0,  10,  50,   0,  16,   0, 
+      0,   0,   0,   0, 134,   0, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+    128,  63,   0,   0, 128, 191, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     66,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,   2,   0, 
+      0,   1,   6,   0,   0,   3, 
+      1,  64,   0,   0,   5,   0, 
+      0,   0,  54,   0,   0,   6, 
+     50,   0,  16,   0,   0,   0, 
+      0,   0, 134,   0,  16, 128, 
+     65,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     66,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128, 191,   2,   0, 
+      0,   1,  23,   0,   0,   1, 
+     86,   0,   0,   5, 130,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10,   0,  16,   0,   1,   0, 
+      0,   0,  86,   0,   0,   6, 
+     18,   0,  16,   0,   1,   0, 
+      0,   0,  10, 128,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  72,   0,   0, 141, 
+    130,   2,   0, 128,  67,  85, 
+     21,   0, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  14, 
+     16,   0,   0,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  10,   0, 
+     16,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 148,   0,   0,   0, 
+     34,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   7,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   7,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   7,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0
+};

+ 49 - 9
src/gpu/d3d11/SDL_gpu_d3d11.c

@@ -92,17 +92,19 @@ static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87,
 
 // Built-in shaders, compiled with compile_shaders.bat
 
-#define g_FullscreenVert  D3D11_FullscreenVert
-#define g_BlitFrom2D      D3D11_BlitFrom2D
-#define g_BlitFrom2DArray D3D11_BlitFrom2DArray
-#define g_BlitFrom3D      D3D11_BlitFrom3D
-#define g_BlitFromCube    D3D11_BlitFromCube
+#define g_FullscreenVert    D3D11_FullscreenVert
+#define g_BlitFrom2D        D3D11_BlitFrom2D
+#define g_BlitFrom2DArray   D3D11_BlitFrom2DArray
+#define g_BlitFrom3D        D3D11_BlitFrom3D
+#define g_BlitFromCube      D3D11_BlitFromCube
+#define g_BlitFromCubeArray D3D11_BlitFromCubeArray
 #include "D3D11_Blit.h"
 #undef g_FullscreenVert
 #undef g_BlitFrom2D
 #undef g_BlitFrom2DArray
 #undef g_BlitFrom3D
 #undef g_BlitFromCube
+#undef g_BlitFromCubeArray
 
 // Macros
 
@@ -740,7 +742,7 @@ struct D3D11Renderer
     SDL_iconv_t iconv;
 
     // Blit
-    BlitPipelineCacheEntry blitPipelines[4];
+    BlitPipelineCacheEntry blitPipelines[5];
     SDL_GPUSampler *blitNearestSampler;
     SDL_GPUSampler *blitLinearSampler;
 
@@ -1940,7 +1942,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
         desc2D.SampleDesc.Quality = 0;
         desc2D.Usage = isStaging ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT;
 
-        if (createInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
+        if (createInfo->type == SDL_GPU_TEXTURETYPE_CUBE || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
             desc2D.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
         }
         if (isMippable) {
@@ -1963,6 +1965,12 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
                 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
                 srvDesc.TextureCube.MipLevels = desc2D.MipLevels;
                 srvDesc.TextureCube.MostDetailedMip = 0;
+            } else if (createInfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
+                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
+                srvDesc.TextureCubeArray.MipLevels = desc2D.MipLevels;
+                srvDesc.TextureCubeArray.MostDetailedMip = 0;
+                srvDesc.TextureCubeArray.First2DArrayFace = 0;
+                srvDesc.TextureCubeArray.NumCubes = layerCount / 6;
             } else if (createInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
                 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
                 srvDesc.Texture2DArray.MipLevels = desc2D.MipLevels;
@@ -2136,7 +2144,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
 
                     rtvDesc.Format = SDLToD3D11_TextureFormat[createInfo->format];
 
-                    if (createInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
+                    if (createInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
                         rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
                         rtvDesc.Texture2DArray.MipSlice = levelIndex;
                         rtvDesc.Texture2DArray.FirstArraySlice = layerIndex;
@@ -2164,7 +2172,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
                 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
                 uavDesc.Format = format;
 
-                if (createInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
+                if (createInfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE || createInfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
                     uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
                     uavDesc.Texture2DArray.MipSlice = levelIndex;
                     uavDesc.Texture2DArray.FirstArraySlice = layerIndex;
@@ -4316,6 +4324,7 @@ static void D3D11_Blit(
         NULL,
         NULL,
         NULL,
+        NULL,
         &blitPipelines,
         NULL,
         NULL);
@@ -5821,6 +5830,9 @@ static bool D3D11_SupportsTextureFormat(
     if (type == SDL_GPU_TEXTURETYPE_CUBE && !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE)) {
         return false;
     }
+    if (type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY && !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE)) {
+        return false;
+    }
 
     // Are the usage flags supported?
     if ((usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) && !(formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) {
@@ -5952,6 +5964,7 @@ static void D3D11_INTERNAL_InitBlitPipelines(
     SDL_GPUShader *blitFrom2DArrayPixelShader;
     SDL_GPUShader *blitFrom3DPixelShader;
     SDL_GPUShader *blitFromCubePixelShader;
+    SDL_GPUShader *blitFromCubeArrayPixelShader;
     SDL_GPUGraphicsPipelineCreateInfo blitPipelineCreateInfo;
     SDL_GPUGraphicsPipeline *blitPipeline;
     SDL_GPUSamplerCreateInfo samplerCreateInfo;
@@ -6024,6 +6037,18 @@ static void D3D11_INTERNAL_InitBlitPipelines(
         SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCube pixel shader!");
     }
 
+    // BlitFromCubeArray pixel shader
+    shaderCreateInfo.code = (Uint8 *)D3D11_BlitFromCubeArray;
+    shaderCreateInfo.code_size = sizeof(D3D11_BlitFromCubeArray);
+
+    blitFromCubeArrayPixelShader = D3D11_CreateShader(
+        (SDL_GPURenderer *)renderer,
+        &shaderCreateInfo);
+
+    if (blitFromCubeArrayPixelShader == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCubeArray pixel shader!");
+    }
+
     // BlitFrom2D pipeline
     SDL_zero(blitPipelineCreateInfo);
 
@@ -6098,6 +6123,20 @@ static void D3D11_INTERNAL_InitBlitPipelines(
     renderer->blitPipelines[SDL_GPU_TEXTURETYPE_CUBE].type = SDL_GPU_TEXTURETYPE_CUBE;
     renderer->blitPipelines[SDL_GPU_TEXTURETYPE_CUBE].format = SDL_GPU_TEXTUREFORMAT_INVALID;
 
+    // BlitFromCubeArrayPipeline
+    blitPipelineCreateInfo.fragment_shader = blitFromCubeArrayPixelShader;
+    blitPipeline = D3D11_CreateGraphicsPipeline(
+        (SDL_GPURenderer *)renderer,
+        &blitPipelineCreateInfo);
+
+    if (blitPipeline == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create BlitFromCubeArray pipeline!");
+    }
+
+    renderer->blitPipelines[SDL_GPU_TEXTURETYPE_CUBE_ARRAY].pipeline = blitPipeline;
+    renderer->blitPipelines[SDL_GPU_TEXTURETYPE_CUBE_ARRAY].type = SDL_GPU_TEXTURETYPE_CUBE_ARRAY;
+    renderer->blitPipelines[SDL_GPU_TEXTURETYPE_CUBE_ARRAY].format = SDL_GPU_TEXTUREFORMAT_INVALID;
+
     // Create samplers
     samplerCreateInfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
     samplerCreateInfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
@@ -6137,6 +6176,7 @@ static void D3D11_INTERNAL_InitBlitPipelines(
     D3D11_ReleaseShader((SDL_GPURenderer *)renderer, blitFrom2DArrayPixelShader);
     D3D11_ReleaseShader((SDL_GPURenderer *)renderer, blitFrom3DPixelShader);
     D3D11_ReleaseShader((SDL_GPURenderer *)renderer, blitFromCubePixelShader);
+    D3D11_ReleaseShader((SDL_GPURenderer *)renderer, blitFromCubeArrayPixelShader);
 }
 
 static void D3D11_INTERNAL_DestroyBlitPipelines(

+ 3 - 2
src/gpu/d3d11/compile_shaders.bat

@@ -3,5 +3,6 @@ fxc /T ps_5_0 /E BlitFrom2D /Fh D3D11_BlitFrom2D.h ..\d3dcommon\D3D_Blit.hlsl
 fxc /T ps_5_0 /E BlitFrom2DArray /Fh D3D11_BlitFrom2DArray.h ..\d3dcommon\D3D_Blit.hlsl
 fxc /T ps_5_0 /E BlitFrom3D /Fh D3D11_BlitFrom3D.h ..\d3dcommon\D3D_Blit.hlsl
 fxc /T ps_5_0 /E BlitFromCube /Fh D3D11_BlitFromCube.h ..\d3dcommon\D3D_Blit.hlsl
-copy /b D3D11_FullscreenVert.h+D3D11_BlitFrom2D.h+D3D11_BlitFrom2DArray.h+D3D11_BlitFrom3D.h+D3D11_BlitFromCube.h D3D11_Blit.h
-del D3D11_FullscreenVert.h D3D11_BlitFrom2D.h D3D11_BlitFrom2DArray.h D3D11_BlitFrom3D.h D3D11_BlitFromCube.h
+fxc /T ps_5_0 /E BlitFromCubeArray /Fh D3D11_BlitFromCubeArray.h ..\d3dcommon\D3D_Blit.hlsl
+copy /b D3D11_FullscreenVert.h+D3D11_BlitFrom2D.h+D3D11_BlitFrom2DArray.h+D3D11_BlitFrom3D.h+D3D11_BlitFromCube.h+D3D11_BlitFromCubeArray.h D3D11_Blit.h
+del D3D11_FullscreenVert.h D3D11_BlitFrom2D.h D3D11_BlitFrom2DArray.h D3D11_BlitFrom3D.h D3D11_BlitFromCube.h D3D11_BlitFromCubeArray.h

File diff suppressed because it is too large
+ 574 - 550
src/gpu/d3d12/D3D12_Blit.h


+ 38 - 9
src/gpu/d3d12/SDL_gpu_d3d12.c

@@ -34,11 +34,12 @@
 
 // Built-in shaders, compiled with compile_shaders.bat
 
-#define g_FullscreenVert  D3D12_FullscreenVert
-#define g_BlitFrom2D      D3D12_BlitFrom2D
-#define g_BlitFrom2DArray D3D12_BlitFrom2DArray
-#define g_BlitFrom3D      D3D12_BlitFrom3D
-#define g_BlitFromCube    D3D12_BlitFromCube
+#define g_FullscreenVert    D3D12_FullscreenVert
+#define g_BlitFrom2D        D3D12_BlitFrom2D
+#define g_BlitFrom2DArray   D3D12_BlitFrom2DArray
+#define g_BlitFrom3D        D3D12_BlitFrom3D
+#define g_BlitFromCube      D3D12_BlitFromCube
+#define g_BlitFromCubeArray D3D12_BlitFromCubeArray
 #if defined(SDL_PLATFORM_XBOXSERIES)
 #include "D3D12_Blit_Series.h"
 #elif defined(SDL_PLATFORM_XBOXONE)
@@ -51,6 +52,7 @@
 #undef g_BlitFrom2DArray
 #undef g_BlitFrom3D
 #undef g_BlitFromCube
+#undef g_BlitFromCubeArray
 
 // Macros
 
@@ -587,6 +589,7 @@ struct D3D12Renderer
     SDL_GPUShader *blitFrom2DArrayShader;
     SDL_GPUShader *blitFrom3DShader;
     SDL_GPUShader *blitFromCubeShader;
+    SDL_GPUShader *blitFromCubeArrayShader;
 
     SDL_GPUSampler *blitNearestSampler;
     SDL_GPUSampler *blitLinearSampler;
@@ -2875,6 +2878,13 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
             srvDesc.TextureCube.MipLevels = createinfo->num_levels;
             srvDesc.TextureCube.MostDetailedMip = 0;
             srvDesc.TextureCube.ResourceMinLODClamp = 0;
+        } else if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
+            srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
+            srvDesc.TextureCubeArray.MipLevels = createinfo->num_levels;
+            srvDesc.TextureCubeArray.MostDetailedMip = 0;
+            srvDesc.TextureCubeArray.First2DArrayFace = 0;
+            srvDesc.TextureCubeArray.NumCubes = createinfo->layer_count_or_depth / 6;
+            srvDesc.TextureCubeArray.ResourceMinLODClamp = 0;
         } else if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
             srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
             srvDesc.Texture2DArray.MipLevels = createinfo->num_levels;
@@ -2943,7 +2953,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
 
                     rtvDesc.Format = SDLToD3D12_TextureFormat[createinfo->format];
 
-                    if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
+                    if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
                         rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
                         rtvDesc.Texture2DArray.MipSlice = levelIndex;
                         rtvDesc.Texture2DArray.FirstArraySlice = layerIndex;
@@ -3000,7 +3010,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
 
                 uavDesc.Format = SDLToD3D12_TextureFormat[createinfo->format];
 
-                if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
+                if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
                     uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
                     uavDesc.Texture2DArray.MipSlice = levelIndex;
                     uavDesc.Texture2DArray.FirstArraySlice = layerIndex;
@@ -3628,6 +3638,7 @@ static void D3D12_INTERNAL_ReleaseBlitPipelines(SDL_GPURenderer *driverData)
     D3D12_ReleaseShader(driverData, renderer->blitFrom2DArrayShader);
     D3D12_ReleaseShader(driverData, renderer->blitFrom3DShader);
     D3D12_ReleaseShader(driverData, renderer->blitFromCubeShader);
+    D3D12_ReleaseShader(driverData, renderer->blitFromCubeArrayShader);
 
     for (Uint32 i = 0; i < renderer->blitPipelineCount; i += 1) {
         D3D12_ReleaseGraphicsPipeline(driverData, renderer->blitPipelines[i].pipeline);
@@ -5830,6 +5841,7 @@ static void D3D12_GenerateMipmaps(
         renderer->blitFrom2DArrayShader,
         renderer->blitFrom3DShader,
         renderer->blitFromCubeShader,
+        renderer->blitFromCubeArrayShader,
         &renderer->blitPipelines,
         &renderer->blitPipelineCount,
         &renderer->blitPipelineCapacity);
@@ -5890,6 +5902,7 @@ static void D3D12_Blit(
         renderer->blitFrom2DArrayShader,
         renderer->blitFrom3DShader,
         renderer->blitFromCubeShader,
+        renderer->blitFromCubeArrayShader,
         &renderer->blitPipelines,
         &renderer->blitPipelineCount,
         &renderer->blitPipelineCapacity);
@@ -6027,7 +6040,7 @@ static bool D3D12_INTERNAL_CreateSwapchain(
     windowData->swapchainHeight = height;
 
     // Precache blit pipelines for the swapchain format
-    for (Uint32 i = 0; i < 4; i += 1) {
+    for (Uint32 i = 0; i < 5; i += 1) {
         SDL_GPU_FetchBlitPipeline(
             renderer->sdlGPUDevice,
             (SDL_GPUTextureType)i,
@@ -6407,7 +6420,7 @@ static bool D3D12_INTERNAL_CreateSwapchain(
     windowData->frameCounter = 0;
 
     // Precache blit pipelines for the swapchain format
-    for (Uint32 i = 0; i < 4; i += 1) {
+    for (Uint32 i = 0; i < 5; i += 1) {
         SDL_GPU_FetchBlitPipeline(
             renderer->sdlGPUDevice,
             (SDL_GPUTextureType)i,
@@ -6417,6 +6430,7 @@ static bool D3D12_INTERNAL_CreateSwapchain(
             renderer->blitFrom2DArrayShader,
             renderer->blitFrom3DShader,
             renderer->blitFromCubeShader,
+            renderer->blitFromCubeArrayShader,
             &renderer->blitPipelines,
             &renderer->blitPipelineCount,
             &renderer->blitPipelineCapacity);
@@ -7450,6 +7464,9 @@ static bool D3D12_SupportsTextureFormat(
     if (type == SDL_GPU_TEXTURETYPE_CUBE && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE)) {
         return false;
     }
+    if (type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE)) {
+        return false;
+    }
 
     // Are the usage flags supported?
     if ((usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) {
@@ -7574,6 +7591,18 @@ static void D3D12_INTERNAL_InitBlitResources(
         SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCube pixel shader!");
     }
 
+    // BlitFromCubeArray pixel shader
+    shaderCreateInfo.code = (Uint8 *)D3D12_BlitFromCubeArray;
+    shaderCreateInfo.code_size = sizeof(D3D12_BlitFromCubeArray);
+
+    renderer->blitFromCubeArrayShader = D3D12_CreateShader(
+        (SDL_GPURenderer *)renderer,
+        &shaderCreateInfo);
+
+    if (renderer->blitFromCubeArrayShader == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCubeArray pixel shader!");
+    }
+
     // Create samplers
     samplerCreateInfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
     samplerCreateInfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;

+ 3 - 2
src/gpu/d3d12/compile_shaders.bat

@@ -13,5 +13,6 @@ cd "%~dp0"
 %DXC% -E BlitFrom2DArray -T ps_6_0 -Fh D3D12_BlitFrom2DArray.h ..\d3dcommon\D3D_Blit.hlsl /D D3D12=1
 %DXC% -E BlitFrom3D -T ps_6_0 -Fh D3D12_BlitFrom3D.h ..\d3dcommon\D3D_Blit.hlsl /D D3D12=1
 %DXC% -E BlitFromCube -T ps_6_0  -Fh D3D12_BlitFromCube.h ..\d3dcommon\D3D_Blit.hlsl /D D3D12=1
-copy /b D3D12_FullscreenVert.h+D3D12_BlitFrom2D.h+D3D12_BlitFrom2DArray.h+D3D12_BlitFrom3D.h+D3D12_BlitFromCube.h D3D12_Blit%SUFFIX%
-del D3D12_FullscreenVert.h D3D12_BlitFrom2D.h D3D12_BlitFrom2DArray.h D3D12_BlitFrom3D.h D3D12_BlitFromCube.h
+%DXC% -E BlitFromCubeArray -T ps_6_0 -Fh D3D12_BlitFromCubeArray.h ..\d3dcommon\D3D_Blit.hlsl /D D3D12=1
+copy /b D3D12_FullscreenVert.h+D3D12_BlitFrom2D.h+D3D12_BlitFrom2DArray.h+D3D12_BlitFrom3D.h+D3D12_BlitFromCube.h+D3D12_BlitFromCubeArray.h D3D12_Blit%SUFFIX%
+del D3D12_FullscreenVert.h D3D12_BlitFrom2D.h D3D12_BlitFrom2DArray.h D3D12_BlitFrom3D.h D3D12_BlitFromCube.h D3D12_BlitFromCubeArray.h

+ 27 - 3
src/gpu/d3dcommon/D3D_Blit.hlsl

@@ -27,6 +27,7 @@ Texture2D SourceTexture2D : REG(t0, space2);
 Texture2DArray SourceTexture2DArray : REG(t0, space2);
 Texture3D SourceTexture3D : REG(t0, space2);
 TextureCube SourceTextureCube : REG(t0, space2);
+TextureCubeArray SourceTextureCubeArray : REG(t0, space2);
 sampler SourceSampler : REG(s0, space2);
 
 #if D3D12
@@ -81,11 +82,34 @@ float4 BlitFromCube(VertexToPixel input) : SV_Target0
     switch ((uint)LayerOrDepth) {
         case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
         case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
-        case 2: newCoord = float3(u, -1.0, -v); break; // POSITIVE Y
-        case 3: newCoord = float3(u, 1.0, v); break; // NEGATIVE Y
+        case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
+        case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
         case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
         case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
         default: newCoord = float3(0, 0, 0); break; // silences warning
     }
     return SourceTextureCube.SampleLevel(SourceSampler, newCoord, MipLevel);
-}
+}
+
+#if D3D12
+[RootSignature(BlitRS)]
+#endif
+float4 BlitFromCubeArray(VertexToPixel input) : SV_Target0
+{
+    // Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
+    float3 newCoord;
+    float2 scaledUV = UVLeftTop + UVDimensions * input.tex;
+    float u = 2.0 * scaledUV.x - 1.0;
+    float v = 2.0 * scaledUV.y - 1.0;
+    uint ArrayIndex = (uint)LayerOrDepth / 6;
+    switch ((uint)LayerOrDepth % 6) {
+        case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
+        case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
+        case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
+        case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
+        case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
+        case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
+        default: newCoord = float3(0, 0, 0); break; // silences warning
+    }
+    return SourceTextureCubeArray.SampleLevel(SourceSampler, float4(newCoord, float(ArrayIndex)), MipLevel);
+}

File diff suppressed because it is too large
+ 788 - 1637
src/gpu/metal/Metal_Blit.h


+ 27 - 2
src/gpu/metal/Metal_Blit.metal

@@ -74,8 +74,8 @@ fragment float4 BlitFromCube(
     switch ((uint)sourceRegion.LayerOrDepth) {
         case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
         case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
-        case 2: newCoord = float3(u, -1.0, -v); break; // POSITIVE Y
-        case 3: newCoord = float3(u, 1.0, v); break; // NEGATIVE Y
+        case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
+        case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
         case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
         case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
         default: newCoord = float3(0, 0, 0); break; // silences warning
@@ -83,3 +83,28 @@ fragment float4 BlitFromCube(
     return sourceTexture.sample(sourceSampler, newCoord, level(sourceRegion.MipLevel));
 }
 #endif
+
+#if COMPILE_BlitFromCubeArray
+fragment float4 BlitFromCubeArray(
+    VertexToFragment input [[stage_in]],
+    constant SourceRegion &sourceRegion [[buffer(0)]],
+    texturecube_array<float> sourceTexture [[texture(0)]],
+    sampler sourceSampler [[sampler(0)]])
+{
+    // Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
+    float2 scaledUV = sourceRegion.UVLeftTop + sourceRegion.UVDimensions * input.tex;
+    float u = 2.0 * scaledUV.x - 1.0;
+    float v = 2.0 * scaledUV.y - 1.0;
+    float3 newCoord;
+    switch (((uint)sourceRegion.LayerOrDepth) % 6) {
+        case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
+        case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
+        case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
+        case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
+        case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
+        case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
+        default: newCoord = float3(0, 0, 0); break; // silences warning
+    }
+    return sourceTexture.sample(sourceSampler, newCoord, (uint)sourceRegion.LayerOrDepth / 6, level(sourceRegion.MipLevel));
+}
+#endif

+ 34 - 5
src/gpu/metal/SDL_gpu_metal.m

@@ -307,10 +307,11 @@ static NSUInteger SDLToMetal_SampleCount[] = {
 };
 
 static MTLTextureType SDLToMetal_TextureType[] = {
-    MTLTextureType2D,      // SDL_GPU_TEXTURETYPE_2D
-    MTLTextureType2DArray, // SDL_GPU_TEXTURETYPE_2D_ARRAY
-    MTLTextureType3D,      // SDL_GPU_TEXTURETYPE_3D
-    MTLTextureTypeCube     // SDL_GPU_TEXTURETYPE_CUBE
+    MTLTextureType2D,       // SDL_GPU_TEXTURETYPE_2D
+    MTLTextureType2DArray,  // SDL_GPU_TEXTURETYPE_2D_ARRAY
+    MTLTextureType3D,       // SDL_GPU_TEXTURETYPE_3D
+    MTLTextureTypeCube,     // SDL_GPU_TEXTURETYPE_CUBE
+    MTLTextureTypeCubeArray // SDL_GPU_TEXTURETYPE_CUBE_ARRAY
 };
 
 static SDL_GPUTextureFormat SwapchainCompositionToFormat[] = {
@@ -612,6 +613,7 @@ struct MetalRenderer
     SDL_GPUShader *blitFrom2DArrayShader;
     SDL_GPUShader *blitFrom3DShader;
     SDL_GPUShader *blitFromCubeShader;
+    SDL_GPUShader *blitFromCubeArrayShader;
 
     SDL_GPUSampler *blitNearestSampler;
     SDL_GPUSampler *blitLinearSampler;
@@ -1348,7 +1350,10 @@ static MetalTexture *METAL_INTERNAL_CreateTexture(
     textureDescriptor.depth = (createinfo->type == SDL_GPU_TEXTURETYPE_3D) ? createinfo->layer_count_or_depth : 1;
     textureDescriptor.mipmapLevelCount = createinfo->num_levels;
     textureDescriptor.sampleCount = 1;
-    textureDescriptor.arrayLength = (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) ? createinfo->layer_count_or_depth : 1;
+    textureDescriptor.arrayLength =
+        (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY)
+            ? createinfo->layer_count_or_depth
+            : 1;
     textureDescriptor.storageMode = MTLStorageModePrivate;
 
     textureDescriptor.usage = 0;
@@ -2953,6 +2958,7 @@ static void METAL_Blit(
         renderer->blitFrom2DArrayShader,
         renderer->blitFrom3DShader,
         renderer->blitFromCubeShader,
+        renderer->blitFromCubeArrayShader,
         &renderer->blitPipelines,
         &renderer->blitPipelineCount,
         &renderer->blitPipelineCapacity);
@@ -3466,6 +3472,7 @@ static Uint8 METAL_INTERNAL_CreateSwapchain(
             renderer->blitFrom2DArrayShader,
             renderer->blitFrom3DShader,
             renderer->blitFromCubeShader,
+            renderer->blitFromCubeArrayShader,
             &renderer->blitPipelines,
             &renderer->blitPipelineCount,
             &renderer->blitPipelineCapacity);
@@ -3793,6 +3800,14 @@ static bool METAL_SupportsTextureFormat(
             }
         }
 
+        // Cube arrays are not supported on older iOS devices
+        if (type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
+            if (!([renderer->device supportsFamily:MTLGPUFamilyCommon2] ||
+                  [renderer->device supportsFamily:MTLGPUFamilyApple4])) {
+                return false;
+            }
+        }
+
         switch (format) {
         // Apple GPU exclusive
         case SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM:
@@ -3932,6 +3947,19 @@ static void METAL_INTERNAL_InitBlitResources(
         SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCube fragment shader!");
     }
 
+    // BlitFromCubeArray fragment shader
+    shaderModuleCreateInfo.code = BlitFromCubeArray_metallib;
+    shaderModuleCreateInfo.code_size = BlitFromCubeArray_metallib_len;
+    shaderModuleCreateInfo.entrypoint = "BlitFromCubeArray";
+
+    renderer->blitFromCubeArrayShader = METAL_CreateShader(
+        (SDL_GPURenderer *)renderer,
+        &shaderModuleCreateInfo);
+
+    if (renderer->blitFromCubeArrayShader == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCubeArray fragment shader!");
+    }
+
     // Create samplers
     createinfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
     createinfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
@@ -3979,6 +4007,7 @@ static void METAL_INTERNAL_DestroyBlitResources(
     METAL_ReleaseShader(driverData, renderer->blitFrom2DArrayShader);
     METAL_ReleaseShader(driverData, renderer->blitFrom3DShader);
     METAL_ReleaseShader(driverData, renderer->blitFromCubeShader);
+    METAL_ReleaseShader(driverData, renderer->blitFromCubeArrayShader);
 
     for (Uint32 i = 0; i < renderer->blitPipelineCount; i += 1) {
         METAL_ReleaseGraphicsPipeline(driverData, renderer->blitPipelines[i].pipeline);

+ 6 - 6
src/gpu/metal/compile_shaders.sh

@@ -4,7 +4,7 @@ set -x
 set -e
 cd `dirname "$0"`
 
-shadernames=(FullscreenVert BlitFrom2D BlitFrom2DArray BlitFrom3D BlitFromCube)
+shadernames=(FullscreenVert BlitFrom2D BlitFrom2DArray BlitFrom3D BlitFromCube BlitFromCubeArray)
 
 generate_shaders()
 {
@@ -14,7 +14,7 @@ generate_shaders()
         minversion=$4
 
         for shadername in "${shadernames[@]}"; do
-            xcrun -sdk $sdkplatform metal -c -std=$compileplatform-metal1.1 -m$sdkplatform-version-min=$minversion -Wall -O3 -D COMPILE_$shadername -o ./$shadername.air ./Metal_Blit.metal || exit $?
+            xcrun -sdk $sdkplatform metal -c -std=$compileplatform-metal2.0 -m$sdkplatform-version-min=$minversion -Wall -O3 -D COMPILE_$shadername -o ./$shadername.air ./Metal_Blit.metal || exit $?
             xcrun -sdk $sdkplatform metallib -o $shadername.metallib $shadername.air || exit $?
             xxd -i $shadername.metallib | perl -w -p -e 's/\Aunsigned /const unsigned /;' >./${shadername}_$fileplatform.h
             rm -f $shadername.air $shadername.metallib
@@ -22,10 +22,10 @@ generate_shaders()
 }
 
 generate_shaders macos macos macosx 10.11
-generate_shaders ios ios iphoneos 8.0
-generate_shaders iphonesimulator ios iphonesimulator 8.0
-generate_shaders tvos ios appletvos 9.0
-generate_shaders tvsimulator ios appletvsimulator 9.0
+generate_shaders ios ios iphoneos 11.0
+generate_shaders iphonesimulator ios iphonesimulator 11.0
+generate_shaders tvos ios appletvos 11.0
+generate_shaders tvsimulator ios appletvsimulator 11.0
 
 # Bundle together one mega-header
 catShaders()

+ 5 - 2
src/gpu/vulkan/SDL_gpu_vulkan.c

@@ -5650,7 +5650,7 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
     texture->isMSAAColorTarget = isMSAAColorTarget;
     texture->markedForDestroy = 0;
 
-    if (type == SDL_GPU_TEXTURETYPE_CUBE) {
+    if (type == SDL_GPU_TEXTURETYPE_CUBE || type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
         imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
     } else if (type == SDL_GPU_TEXTURETYPE_3D) {
         imageCreateFlags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
@@ -5734,6 +5734,8 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
 
         if (type == SDL_GPU_TEXTURETYPE_CUBE) {
             imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
+        } else if (type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY){
+            imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
         } else if (type == SDL_GPU_TEXTURETYPE_3D) {
             imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
         } else if (type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
@@ -10944,7 +10946,7 @@ static bool VULKAN_SupportsTextureFormat(
         vulkanUsage |= VK_IMAGE_USAGE_STORAGE_BIT;
     }
 
-    if (type == SDL_GPU_TEXTURETYPE_CUBE) {
+    if (type == SDL_GPU_TEXTURETYPE_CUBE || type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
         createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
     }
 
@@ -11531,6 +11533,7 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
     SDL_zero(desiredDeviceFeatures);
     desiredDeviceFeatures.independentBlend = VK_TRUE;
     desiredDeviceFeatures.samplerAnisotropy = VK_TRUE;
+    desiredDeviceFeatures.imageCubeArray = VK_TRUE;
 
     if (haveDeviceFeatures.fillModeNonSolid) {
         desiredDeviceFeatures.fillModeNonSolid = VK_TRUE;

Some files were not shown because too many files changed in this diff