Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Texture Format cleanup and documentation #217

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 89 additions & 36 deletions include/SDL3/SDL_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,55 +78,116 @@ typedef enum SDL_GpuIndexElementSize
SDL_GPU_INDEXELEMENTSIZE_32BIT
} SDL_GpuIndexElementSize;

/* Texture format support varies depending on driver, hardware, and usage flags.
* In general, you should use SDL_GpuSupportsTextureFormat to query if a format
* is supported before using it. However, there are a few guaranteed formats.
*
* For SAMPLER usage, the following formats are universally supported:
* - R8G8B8A8_UNORM
* - B8G8R8A8_UNORM
* - R8_UNORM
* - R8G8_SNORM
* - R8G8B8A8_SNORM
* - R16_FLOAT
* - R16G16_FLOAT
* - R16G16B16A16_FLOAT
* - R32_FLOAT
* - R32G32_FLOAT
* - R32G32B32A32_FLOAT
* - R8G8B8A8_UNORM_SRGB
* - B8G8R8A8_UNORM_SRGB
* - D16_UNORM
*
* For COLOR_TARGET usage, the following formats are universally supported:
* - R8G8B8A8_UNORM
* - B8G8R8A8_UNORM
* - R8_UNORM
* - R16_FLOAT
* - R16G16_FLOAT
* - R16G16B16A16_FLOAT
* - R32_FLOAT
* - R32G32_FLOAT
* - R32G32B32A32_FLOAT
* - R8_UINT
* - R8G8_UINT
* - R8G8B8A8_UINT
* - R16_UINT
* - R16G16_UINT
* - R16G16B16A16_UINT
* - R8G8B8A8_UNORM_SRGB
* - B8G8R8A8_UNORM_SRGB
*
* For STORAGE usages, the following formats are universally supported:
* - R8G8B8A8_UNORM
* - R8G8B8A8_SNORM
* - R16G16B16A16_FLOAT
* - R32_FLOAT
* - R32G32_FLOAT
* - R32G32B32A32_FLOAT
* - R8_UINT
* - R8G8_UINT
* - R8G8B8A8_UINT
* - R16_UINT
* - R16G16_UINT
* - R16G16B16A16_UINT
*
* For DEPTH_STENCIL_TARGET usage, the following formats are universally supported:
* - D16_UNORM
* - Either (but not necessarily both!) D24_UNORM or D32_SFLOAT
* - Either (but not necessarily both!) D24_UNORM_S8_UINT or D32_SFLOAT_S8_UINT
*
* Unless D16_UNORM is sufficient for your purposes, always check which
* of D24/D32 is supported before creating a depth-stencil texture!
*/
typedef enum SDL_GpuTextureFormat
{
SDL_GPU_TEXTUREFORMAT_INVALID = -1,

/* Unsigned Normalized Float Color Formats */
SDL_GPU_TEXTUREFORMAT_R8G8B8A8,
SDL_GPU_TEXTUREFORMAT_B8G8R8A8,
SDL_GPU_TEXTUREFORMAT_B5G6R5,
SDL_GPU_TEXTUREFORMAT_B5G5R5A1,
SDL_GPU_TEXTUREFORMAT_B4G4R4A4,
SDL_GPU_TEXTUREFORMAT_R10G10B10A2,
SDL_GPU_TEXTUREFORMAT_R16G16,
SDL_GPU_TEXTUREFORMAT_R16G16B16A16,
SDL_GPU_TEXTUREFORMAT_R8,
SDL_GPU_TEXTUREFORMAT_A8,
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM,
SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM,
SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM,
SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM,
SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM,
SDL_GPU_TEXTUREFORMAT_R16G16_UNORM,
SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM,
SDL_GPU_TEXTUREFORMAT_R8_UNORM,
SDL_GPU_TEXTUREFORMAT_A8_UNORM,
/* Compressed Unsigned Normalized Float Color Formats */
SDL_GPU_TEXTUREFORMAT_BC1,
SDL_GPU_TEXTUREFORMAT_BC2,
SDL_GPU_TEXTUREFORMAT_BC3,
SDL_GPU_TEXTUREFORMAT_BC7,
SDL_GPU_TEXTUREFORMAT_BC1_UNORM,
SDL_GPU_TEXTUREFORMAT_BC2_UNORM,
SDL_GPU_TEXTUREFORMAT_BC3_UNORM,
SDL_GPU_TEXTUREFORMAT_BC7_UNORM,
/* Signed Normalized Float Color Formats */
SDL_GPU_TEXTUREFORMAT_R8G8_SNORM,
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM,
/* Signed Float Color Formats */
SDL_GPU_TEXTUREFORMAT_R16_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R16G16_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R32_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R32G32_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R32G32B32A32_SFLOAT,
SDL_GPU_TEXTUREFORMAT_R16_FLOAT,
SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT,
SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT,
SDL_GPU_TEXTUREFORMAT_R32_FLOAT,
SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT,
SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT,
/* Unsigned Integer Color Formats */
SDL_GPU_TEXTUREFORMAT_R8_UINT,
SDL_GPU_TEXTUREFORMAT_R8G8_UINT,
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT,
SDL_GPU_TEXTUREFORMAT_R16_UINT,
SDL_GPU_TEXTUREFORMAT_R16G16_UINT,
SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT,
/* SRGB Color Formats */
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SRGB,
SDL_GPU_TEXTUREFORMAT_B8G8R8A8_SRGB,
/* Compressed SRGB Color Formats */
SDL_GPU_TEXTUREFORMAT_BC3_SRGB,
SDL_GPU_TEXTUREFORMAT_BC7_SRGB,
/* SRGB Unsigned Normalized Color Formats */
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB,
SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB,
/* Compressed SRGB Unsigned Normalized Color Formats */
SDL_GPU_TEXTUREFORMAT_BC3_UNORM_SRGB,
SDL_GPU_TEXTUREFORMAT_BC7_UNORM_SRGB,
/* Depth Formats */
SDL_GPU_TEXTUREFORMAT_D16_UNORM,
SDL_GPU_TEXTUREFORMAT_D24_UNORM,
SDL_GPU_TEXTUREFORMAT_D32_SFLOAT,
SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT,
SDL_GPU_TEXTUREFORMAT_D32_SFLOAT_S8_UINT
SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT
} SDL_GpuTextureFormat;

typedef enum SDL_GpuTextureUsageFlagBits
Expand Down Expand Up @@ -1079,14 +1140,6 @@ extern SDL_DECLSPEC SDL_GpuShader *SDLCALL SDL_GpuCreateShader(
* If you request a sample count higher than the hardware supports,
* the implementation will automatically fall back to the highest available sample count.
*
* For depth textures, the hardware support matrix looks as follows:
* - D16_UNORM is guaranteed to always be supported.
* - It's guaranteed that either D24_UNORM or D32_SFLOAT will be supported.
* - It's guaranteed that either D24_UNORM_S8_UINT or D32_SFLOAT_S8_UINT will be supported.
* Therefore, unless D16 is sufficient for your purposes, you should always call
* SDL_GpuSupportsTextureFormat to determine which of D24/D32 are supported by the GPU
* before creating a depth texture.
*
* \param device a GPU Context
* \param textureCreateInfo a struct describing the state of the texture to create
* \returns a texture object on success, or NULL on failure
Expand Down
46 changes: 23 additions & 23 deletions src/gpu/SDL_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,43 +513,43 @@ Uint32 SDL_GpuTextureFormatTexelBlockSize(
SDL_GpuTextureFormat textureFormat)
{
switch (textureFormat) {
case SDL_GPU_TEXTUREFORMAT_BC1:
case SDL_GPU_TEXTUREFORMAT_BC1_UNORM:
return 8;
case SDL_GPU_TEXTUREFORMAT_BC2:
case SDL_GPU_TEXTUREFORMAT_BC3:
case SDL_GPU_TEXTUREFORMAT_BC7:
case SDL_GPU_TEXTUREFORMAT_BC3_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC2_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC7_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_UNORM_SRGB:
return 16;
case SDL_GPU_TEXTUREFORMAT_R8:
case SDL_GPU_TEXTUREFORMAT_A8:
case SDL_GPU_TEXTUREFORMAT_R8_UNORM:
case SDL_GPU_TEXTUREFORMAT_A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8_UINT:
return 1;
case SDL_GPU_TEXTUREFORMAT_B5G6R5:
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4:
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1:
case SDL_GPU_TEXTUREFORMAT_R16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM:
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM:
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R8G8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8_UINT:
case SDL_GPU_TEXTUREFORMAT_R16_UINT:
return 2;
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_SRGB:
case SDL_GPU_TEXTUREFORMAT_R32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_R32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2:
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16_UINT:
return 4;
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16:
case SDL_GPU_TEXTUREFORMAT_R32G32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT:
return 8;
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
return 16;
default:
SDL_assert_release(!"Unrecognized TextureFormat!");
Expand Down
72 changes: 36 additions & 36 deletions src/gpu/SDL_sysgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,47 +69,47 @@ typedef struct BlitPipelineCacheEntry

/* Internal Helper Utilities */

#define SDL_GPU_TEXTUREFORMAT_MAX (SDL_GPU_TEXTUREFORMAT_D32_SFLOAT_S8_UINT + 1)
#define SDL_GPU_TEXTUREFORMAT_MAX (SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT + 1)
#define SDL_GPU_SWAPCHAINCOMPOSITION_MAX (SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048 + 1)
#define SDL_GPU_PRESENTMODE_MAX (SDL_GPU_PRESENTMODE_MAILBOX + 1)

static inline Sint32 Texture_GetBlockSize(
SDL_GpuTextureFormat format)
{
switch (format) {
case SDL_GPU_TEXTUREFORMAT_BC1:
case SDL_GPU_TEXTUREFORMAT_BC2:
case SDL_GPU_TEXTUREFORMAT_BC3:
case SDL_GPU_TEXTUREFORMAT_BC7:
case SDL_GPU_TEXTUREFORMAT_BC3_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC1_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC2_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC7_UNORM:
case SDL_GPU_TEXTUREFORMAT_BC3_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_BC7_UNORM_SRGB:
return 4;
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8:
case SDL_GPU_TEXTUREFORMAT_B5G6R5:
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1:
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4:
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2:
case SDL_GPU_TEXTUREFORMAT_R16G16:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16:
case SDL_GPU_TEXTUREFORMAT_R8:
case SDL_GPU_TEXTUREFORMAT_A8:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM:
case SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM:
case SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM:
case SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8_UNORM:
case SDL_GPU_TEXTUREFORMAT_A8_UNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM:
case SDL_GPU_TEXTUREFORMAT_R16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_R16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_R8_UINT:
case SDL_GPU_TEXTUREFORMAT_R8G8_UINT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT:
case SDL_GPU_TEXTUREFORMAT_R16_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16_UINT:
case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_SRGB:
case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
return 1;
default:
SDL_assert_release(!"Unrecognized TextureFormat!");
Expand All @@ -123,9 +123,9 @@ static inline SDL_bool IsDepthFormat(
switch (format) {
case SDL_GPU_TEXTUREFORMAT_D16_UNORM:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM:
case SDL_GPU_TEXTUREFORMAT_D32_SFLOAT:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT:
case SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_SFLOAT_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT:
return SDL_TRUE;

default:
Expand All @@ -138,7 +138,7 @@ static inline SDL_bool IsStencilFormat(
{
switch (format) {
case SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_SFLOAT_S8_UINT:
case SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT:
return SDL_TRUE;

default:
Expand Down Expand Up @@ -174,10 +174,10 @@ static inline Uint32 BytesPerRow(
{
Uint32 blocksPerRow = width;

if (format == SDL_GPU_TEXTUREFORMAT_BC1 ||
format == SDL_GPU_TEXTUREFORMAT_BC2 ||
format == SDL_GPU_TEXTUREFORMAT_BC3 ||
format == SDL_GPU_TEXTUREFORMAT_BC7) {
if (format == SDL_GPU_TEXTUREFORMAT_BC1_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC2_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC3_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC7_UNORM) {
blocksPerRow = (width + 3) / 4;
}

Expand All @@ -192,10 +192,10 @@ static inline Sint32 BytesPerImage(
Uint32 blocksPerRow = width;
Uint32 blocksPerColumn = height;

if (format == SDL_GPU_TEXTUREFORMAT_BC1 ||
format == SDL_GPU_TEXTUREFORMAT_BC2 ||
format == SDL_GPU_TEXTUREFORMAT_BC3 ||
format == SDL_GPU_TEXTUREFORMAT_BC7) {
if (format == SDL_GPU_TEXTUREFORMAT_BC1_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC2_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC3_UNORM ||
format == SDL_GPU_TEXTUREFORMAT_BC7_UNORM) {
blocksPerRow = (width + 3) / 4;
blocksPerColumn = (height + 3) / 4;
}
Expand Down
Loading
Loading