diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index 66455d67b..89d5000a2 100644 --- a/include/SDL3/SDL_gpu.h +++ b/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 /** diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index c60e930c0..06cc432a9 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 c03a633f1..6de388483 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 59c32eaaf..e6dcb8b80 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 3607a7954..c550c7a57 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_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); +} diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h index f06ae62d6..51fd06fcc 100644 --- a/src/gpu/SDL_sysgpu.h +++ b/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 diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index faed52bb6..d60d69d4b 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