Skip to content

Use the correct pixel formats for Vulkan on big endian #9905

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ccawley2011
Copy link
Contributor

The new formats more closely match how the specifications describe how packed vs. byte formats are stored and should work in theory on both big and little endian. Support for SDL_PIXELFORMAT_XRGB8888 was removed because it wasn't clear how the existing code handled missing alpha components.

I'm not sure about SDL_PIXELFORMAT_XBGR2101010, but I don't know how to test it.

@slouken
Copy link
Collaborator

slouken commented May 27, 2024

@danginsburg, can you check this?

SDL_PIXELFORMAT_XRGB8888 should be handled like ARGB8888 but blending operations treat the alpha channel as opaque.

@ccawley2011
Copy link
Contributor Author

As an aside, it would be nice to support some of the 16-bit packed formats like VK_FORMAT_R4G4B4A4_UNORM_PACK16, but since none of them have SRGB variants I'm not sure how to correctly approach this.

@slouken
Copy link
Collaborator

slouken commented May 27, 2024

As an aside, it would be nice to support some of the 16-bit packed formats like VK_FORMAT_R4G4B4A4_UNORM_PACK16, but since none of them have SRGB variants I'm not sure how to correctly approach this.

In practice I haven't seen them being used for rendering. Usually textures are converted to RGBA or a compressed texture format.

@danginsburg
Copy link
Contributor

I don't really have the context to understand what the impact of this change would be. What is removing SDL_PIXELFORMAT_ARGB8888 and SDL_PIXELFORMAT_XRGB8888 from SDL_AddSupportedTextureFormat and replacing them with SDL_PIXELFORMAT_RGBA32 and SDL_PIXELFORMAT_BGRA32 going to do?

Also, I wonder if you need to do optimalTilingSupport checks for some of these since for example R8G8B8_SRGB/UNORM have pretty limited support in the wild (see vulkan.gpuinfo.org).

@ccawley2011
Copy link
Contributor Author

I don't really have the context to understand what the impact of this change would be. What is removing SDL_PIXELFORMAT_ARGB8888 and SDL_PIXELFORMAT_XRGB8888 from SDL_AddSupportedTextureFormat and replacing them with SDL_PIXELFORMAT_RGBA32 and SDL_PIXELFORMAT_BGRA32 going to do?

The Vulkan specs state that VK_FORMAT_B8G8R8A8_UNORM specifies a four-component, 32-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3., however SDL_PIXELFORMAT_ARGB8888 specifies a format with an 8-bit A component in bits 24..31, an 8-bit R component in bits 16..23, an 8-bit G component in bits 8..15, and an 8-bit B component in bits 0..7. On little endian machines these both mean the same thing, but on big endian machines these have the components in the opposite order to each other. SDL_PIXELFORMAT_BGRA32 is an alias to handle this difference.

Also, I wonder if you need to do optimalTilingSupport checks for some of these since for example R8G8B8_SRGB/UNORM have pretty limited support in the wild (see vulkan.gpuinfo.org).

That probably depends on if it's still faster than converting in software. It's listed after the R8G8B8A8 formats so it shouldn't be picked as a default for the most part, but it may still be nice to extend the SDL render API to report that certain supported formats are slower.

In practice I haven't seen them being used for rendering. Usually textures are converted to RGBA or a compressed texture format.

I'm mainly interested in the 16-bit pixel formats for dynamic textures in emulators, game reimplementations and video decoders, but it should be useful for static images on lower-end devices as well (such as .bmp and .tga).

SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRA32);
#if SDL_BYTEORDER != SDL_LIL_ENDIAN
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ABGR8888);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that the same as:

SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're the same on little endian, but different on big endian.

@slouken
Copy link
Collaborator

slouken commented May 28, 2024

By the way, we're not trying to stuff in all the formats that can be supported, we're trying to include the common formats that are fast for current drivers. If a format is allowed according to the spec, but mobile GPU vendors implement slow paths for access, for example, we wouldn't list those formats. The 3-byte RGB formats come to mind, and the 16-bit formats might be in a similar situation.

If a format is supported but slow, it's actually better to leave it off, since SDL will convert textures to fast formats during texture creation and upload.

@danginsburg
Copy link
Contributor

That probably depends on if it's still faster than converting in software. It's listed after the R8G8B8A8 formats so it shouldn't be picked as a default for the most part, but it may still be nice to extend the SDL render API to report that certain supported formats are slower.

It's not a performance thing, for non-mandatory formats you need to check vkGetPhysicalDeviceFormatProperties to see if it's supported for the uses. See https://registry.khronos.org/vulkan/specs/1.3/html/vkspec.html#formats-mandatory-features-32bit for the list of mandatory formats. I think the previously exposed formats were mandatory so not checked, if not that's a bug.

@slouken
Copy link
Collaborator

slouken commented Aug 6, 2024

@ccawley2011, can you update this PR to check vkGetPhysicalDeviceFormatProperties for the appropriate formats?

@ccawley2011 ccawley2011 force-pushed the vulkan-rgba32 branch 2 times, most recently from b1b16a4 to 165bfe9 Compare June 29, 2025 14:32
@ccawley2011
Copy link
Contributor Author

I've updated this PR to remove the 24-bit pixel format, leaving only the endian fixes. The newly added VK_FORMAT_A8B8G8R8_UNORM_PACK32 is described as mandatory under the same circumstances that the other two 8888 formats are, so it shouldn't be necessary to check for support.

@ccawley2011 ccawley2011 changed the title Support more pixel formats with the Vulkan renderer Use correct pixel formats for Vulkan on big endian Jun 29, 2025
@ccawley2011 ccawley2011 changed the title Use correct pixel formats for Vulkan on big endian Use the correct pixel formats for Vulkan on big endian Jun 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants