Browse Source

GPU: Add SDL_CalculateGPUTextureFormatSize (#11146)

---------

Co-authored-by: Sam Lantinga <slouken@libsdl.org>
Evan Hemsley 6 months ago
parent
commit
6ea4a66451

+ 17 - 0
include/SDL3/SDL_gpu.h

@@ -3714,6 +3714,23 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GPUTextureSupportsSampleCount(
     SDL_GPUTextureFormat format,
     SDL_GPUSampleCount sample_count);
 
+/**
+ * Calculate the size in bytes of a texture format with dimensions.
+ *
+ * \param format a texture format.
+ * \param width width in pixels.
+ * \param height height in pixels.
+ * \param depth_or_layer_count depth for 3D textures or layer count otherwise.
+ * \returns the size of a texture with this format and dimensions.
+ *
+ * \since This function is available since SDL 3.1.5.
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_CalculateGPUTextureFormatSize(
+    SDL_GPUTextureFormat format,
+    Uint32 width,
+    Uint32 height,
+    Uint32 depth_or_layer_count);
+
 #ifdef SDL_PLATFORM_GDK
 
 /**

+ 1 - 0
src/dynapi/SDL_dynapi.sym

@@ -1178,6 +1178,7 @@ SDL3_0.0.0 {
     SDL_wcstol;
     SDL_StepBackUTF8;
     SDL_DelayPrecise;
+    SDL_CalculateGPUTextureFormatSize;
     # extra symbols go here (don't modify this line)
   local: *;
 };

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -1203,3 +1203,4 @@
 #define SDL_wcstol SDL_wcstol_REAL
 #define SDL_StepBackUTF8 SDL_StepBackUTF8_REAL
 #define SDL_DelayPrecise SDL_DelayPrecise_REAL
+#define SDL_CalculateGPUTextureFormatSize SDL_CalculateGPUTextureFormatSize_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -1209,3 +1209,4 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),r
 SDL_DYNAPI_PROC(long,SDL_wcstol,(const wchar_t *a, wchar_t **b, int c),(a,b,c),return)
 SDL_DYNAPI_PROC(Uint32,SDL_StepBackUTF8,(const char *a, const char **b),(a,b),return)
 SDL_DYNAPI_PROC(void,SDL_DelayPrecise,(Uint64 a),(a),)
+SDL_DYNAPI_PROC(Uint32,SDL_CalculateGPUTextureFormatSize,(SDL_GPUTextureFormat a, Uint32 b, Uint32 c, Uint32 d),(a,b,c,d),return)

+ 13 - 0
src/gpu/SDL_gpu.c

@@ -2796,3 +2796,16 @@ void SDL_ReleaseGPUFence(
         device->driverData,
         fence);
 }
+
+Uint32 SDL_CalculateGPUTextureFormatSize(
+    SDL_GPUTextureFormat format,
+    Uint32 width,
+    Uint32 height,
+    Uint32 depth_or_layer_count)
+{
+    Uint32 blockWidth = Texture_GetBlockWidth(format);
+    Uint32 blockHeight = Texture_GetBlockHeight(format);
+    Uint32 blocksPerRow = (width + blockWidth - 1) / blockWidth;
+    Uint32 blocksPerColumn = (height + blockHeight - 1) / blockHeight;
+    return depth_or_layer_count * blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
+}

+ 0 - 12
src/gpu/SDL_sysgpu.h

@@ -362,18 +362,6 @@ static inline Uint32 BytesPerRow(
     return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format);
 }
 
-static inline Sint32 BytesPerImage(
-    Uint32 width,
-    Uint32 height,
-    SDL_GPUTextureFormat format)
-{
-    Uint32 blockWidth = Texture_GetBlockWidth(format);
-    Uint32 blockHeight = Texture_GetBlockHeight(format);
-    Uint32 blocksPerRow = (width + blockWidth - 1) / blockWidth;
-    Uint32 blocksPerColumn = (height + blockHeight - 1) / blockHeight;
-    return blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
-}
-
 // GraphicsDevice Limits
 
 #define MAX_TEXTURE_SAMPLERS_PER_STAGE 16

+ 1 - 1
src/gpu/metal/SDL_gpu_metal.m

@@ -1752,7 +1752,7 @@ static void METAL_UploadToTexture(
                  copyFromBuffer:bufferContainer->activeBuffer->handle
                    sourceOffset:source->offset
               sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
-            sourceBytesPerImage:BytesPerImage(destination->w, destination->h, textureContainer->header.info.format)
+            sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d)
                      sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
                       toTexture:metalTexture->handle
                destinationSlice:destination->layer