From d9503632d43dfa026d72334da5fcb33387550a67 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 9 Oct 2024 21:19:48 -0700 Subject: [PATCH] GPU: Add SDL_CalculateGPUTextureFormatSize --- include/SDL3/SDL_gpu.h | 17 +++++++++++++++++ src/dynapi/SDL_dynapi.sym | 1 + src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/gpu/SDL_gpu.c | 13 +++++++++++++ src/gpu/SDL_sysgpu.h | 15 --------------- src/gpu/metal/SDL_gpu_metal.m | 2 +- 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index b9e7442f995e6f..210330fe49394d 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -3715,6 +3715,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 depth in pixels. + * \returns the size of a texture with this format and dimensions. + * + * \since This function is available since SDL 3.2.0. + */ +extern SDL_DECLSPEC Uint32 SDLCALL SDL_CalculateGPUTextureFormatSize( + SDL_GPUTextureFormat format, + Uint32 width, + Uint32 height, + Uint32 depth); + #ifdef SDL_PLATFORM_GDK /** diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index c60e930c03666a..06cc432a93f958 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/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: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c03a633f12739f..6de3884830abff 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/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 diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 59c32eaaf55b5e..e6dcb8b8028ba5 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/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) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index 3607a7954063ff..89eb0ce6a19161 100644 --- a/src/gpu/SDL_gpu.c +++ b/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) +{ + Uint32 pixelRowsPerBlock = Texture_GetBlockSize(format); + Uint32 pixelColumnsPerBlock = pixelRowsPerBlock; + Uint32 blocksPerRow = (width + pixelRowsPerBlock - 1) / pixelRowsPerBlock; + Uint32 blocksPerColumn = (height + pixelColumnsPerBlock - 1) / pixelColumnsPerBlock; + return depth * blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format); +} diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h index ba48c6cc1cc169..0c0db5e920895f 100644 --- a/src/gpu/SDL_sysgpu.h +++ b/src/gpu/SDL_sysgpu.h @@ -208,21 +208,6 @@ static inline Uint32 BytesPerRow( return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format); } -static inline Sint32 BytesPerImage( - Uint32 width, - Uint32 height, - SDL_GPUTextureFormat format) -{ - Uint32 blocksPerRow = width; - Uint32 blocksPerColumn = height; - Uint32 pixelRowsPerBlock = Texture_GetBlockSize(format); - Uint32 pixelColumnsPerBlock = pixelRowsPerBlock; - - blocksPerRow = (width + pixelRowsPerBlock - 1) / pixelRowsPerBlock; - blocksPerColumn = (height + pixelColumnsPerBlock - 1) / pixelColumnsPerBlock; - return blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format); -} - // GraphicsDevice Limits #define MAX_TEXTURE_SAMPLERS_PER_STAGE 16 diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 84515eaf025dab..f405c91fe842f5 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/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