Added support for linear and pixel art scaling for palettized textures

This commit is contained in:
Sam Lantinga
2025-10-04 14:16:02 -07:00
parent e1fde46a6a
commit 134b47730b
43 changed files with 11348 additions and 7598 deletions

View File

@@ -70,10 +70,12 @@ static const float TONEMAP_CHROME = 2;
//static const float TEXTURETYPE_NONE = 0;
static const float TEXTURETYPE_RGB = 1;
static const float TEXTURETYPE_RGB_PIXELART = 2;
static const float TEXTURETYPE_PALETTE = 3;
static const float TEXTURETYPE_NV12 = 4;
static const float TEXTURETYPE_NV21 = 5;
static const float TEXTURETYPE_YUV = 6;
static const float TEXTURETYPE_PALETTE_NEAREST = 3;
static const float TEXTURETYPE_PALETTE_LINEAR = 4;
static const float TEXTURETYPE_PALETTE_PIXELART = 5;
static const float TEXTURETYPE_NV12 = 6;
static const float TEXTURETYPE_NV21 = 7;
static const float TEXTURETYPE_YUV = 8;
static const float INPUTTYPE_UNSPECIFIED = 0;
static const float INPUTTYPE_SRGB = 1;
@@ -2599,8 +2601,20 @@ static void D3D12_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderC
switch (texture->format) {
case SDL_PIXELFORMAT_INDEX8:
constants->texture_type = TEXTURETYPE_PALETTE;
constants->input_type = INPUTTYPE_UNSPECIFIED;
switch (cmd->data.draw.texture_scale_mode) {
case SDL_SCALEMODE_NEAREST:
constants->texture_type = TEXTURETYPE_PALETTE_NEAREST;
break;
case SDL_SCALEMODE_LINEAR:
constants->texture_type = TEXTURETYPE_PALETTE_LINEAR;
break;
case SDL_SCALEMODE_PIXELART:
constants->texture_type = TEXTURETYPE_PALETTE_PIXELART;
break;
default:
SDL_assert(!"Unknown scale mode");
break;
}
break;
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
@@ -2622,10 +2636,6 @@ static void D3D12_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderC
default:
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART) {
constants->texture_type = TEXTURETYPE_RGB_PIXELART;
constants->texture_width = texture->w;
constants->texture_height = texture->h;
constants->texel_width = 1.0f / constants->texture_width;
constants->texel_height = 1.0f / constants->texture_height;
} else {
constants->texture_type = TEXTURETYPE_RGB;
}
@@ -2640,6 +2650,15 @@ static void D3D12_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderC
break;
}
if (constants->texture_type == TEXTURETYPE_PALETTE_LINEAR ||
constants->texture_type == TEXTURETYPE_PALETTE_PIXELART ||
constants->texture_type == TEXTURETYPE_RGB_PIXELART) {
constants->texture_width = texture->w;
constants->texture_height = texture->h;
constants->texel_width = 1.0f / constants->texture_width;
constants->texel_height = 1.0f / constants->texture_height;
}
constants->sdr_white_point = texture->SDR_white_point;
if (renderer->target) {
@@ -2848,7 +2867,7 @@ static bool D3D12_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *
return true;
}
static D3D12_CPU_DESCRIPTOR_HANDLE *D3D12_GetSamplerState(D3D12_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
static D3D12_CPU_DESCRIPTOR_HANDLE *D3D12_GetSamplerState(D3D12_RenderData *data, SDL_PixelFormat format, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v)
{
Uint32 key = RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v);
SDL_assert(key < SDL_arraysize(data->samplers));
@@ -2867,7 +2886,12 @@ static D3D12_CPU_DESCRIPTOR_HANDLE *D3D12_GetSamplerState(D3D12_RenderData *data
break;
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
case SDL_SCALEMODE_LINEAR:
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
if (format == SDL_PIXELFORMAT_INDEX8) {
// We'll do linear sampling in the shader
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
} else {
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
}
break;
default:
SDL_SetError("Unknown scale mode: %d", scale_mode);
@@ -2923,7 +2947,7 @@ static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *
textureData->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
shaderResources[numShaderResources++] = textureData->mainTextureResourceView;
textureSampler = D3D12_GetSamplerState(rendererData, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
textureSampler = D3D12_GetSamplerState(rendererData, texture->format, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode_u, cmd->data.draw.texture_address_mode_v);
if (!textureSampler) {
return false;
}
@@ -2936,7 +2960,7 @@ static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *
palette->resourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
shaderResources[numShaderResources++] = palette->resourceView;
textureSampler = D3D12_GetSamplerState(rendererData, SDL_SCALEMODE_NEAREST, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
textureSampler = D3D12_GetSamplerState(rendererData, SDL_PIXELFORMAT_UNKNOWN, SDL_SCALEMODE_NEAREST, SDL_TEXTURE_ADDRESS_CLAMP, SDL_TEXTURE_ADDRESS_CLAMP);
if (!textureSampler) {
return false;
}