Set the texture palette before setting pixel data

This is a better fix for https://github.com/libsdl-org/SDL/issues/16227.

The original problem was that the newly created texture didn't have any palette, so when the surface data was set, colors couldn't be mapped to pixel index values. The old fix temporarily set the texture palette to the surface palette, copied the surface data, and then set the texture palette to a copy of the surface palette. This caused Vulkan validation errors because we were deleting the original palette which was still referenced by the active command buffer. Instead, we'll create the palette that we want the texture to have to start with, then copy the surface data once that's set.
This commit is contained in:
Sam Lantinga
2026-09-09 09:26:21 -07:00
parent 8f9738372c
commit a55e059f84

View File

@@ -1700,8 +1700,22 @@ SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, S
static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
{
bool direct_update;
if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && surface->palette) {
// Copy the palette to the new texture
SDL_Palette *existing = surface->palette;
SDL_Palette *palette = SDL_CreatePalette(existing->ncolors);
if (palette &&
SDL_SetPaletteColors(palette, existing->colors, 0, existing->ncolors) &&
SDL_SetTexturePalette(texture, palette)) {
// The texture has a reference to the palette now
SDL_DestroyPalette(palette);
} else {
SDL_DestroyPalette(palette);
return false;
}
}
bool direct_update;
if (surface->format == texture->format &&
SDL_GetSurfaceColorspace(surface) == texture->colorspace) {
if (SDL_ISPIXELFORMAT_INDEXED(surface->format)) {
@@ -1740,21 +1754,6 @@ static bool SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, S
}
}
if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && surface->palette) {
// Copy the palette to the new texture
SDL_Palette *existing = surface->palette;
SDL_Palette *palette = SDL_CreatePalette(existing->ncolors);
if (palette &&
SDL_SetPaletteColors(palette, existing->colors, 0, existing->ncolors) &&
SDL_SetTexturePalette(texture, palette)) {
// The texture has a reference to the palette now
SDL_DestroyPalette(palette);
} else {
SDL_DestroyPalette(palette);
return false;
}
}
if (SDL_ISPIXELFORMAT_INDEXED(texture->format) && SDL_SurfaceHasColorKey(surface)) {
Uint32 key;
SDL_Color col;
@@ -1885,7 +1884,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, surface->w);
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, surface->h);
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER, surface->palette);
texture = SDL_CreateTextureWithProperties(renderer, props);
SDL_DestroyProperties(props);