diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index 14bc1a5bdd..9f6d42f2e5 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -302,49 +302,35 @@ static UINT D3D12_Align(UINT location, UINT alignment) return (location + (alignment - 1)) & ~(alignment - 1); } +static const struct { + Uint32 sdl; + DXGI_FORMAT unorm; + DXGI_FORMAT srgb; +} dxgi_format_map[] = { + { SDL_PIXELFORMAT_ARGB8888, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB }, + { SDL_PIXELFORMAT_ABGR8888, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, + { SDL_PIXELFORMAT_XRGB8888, DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB }, + { SDL_PIXELFORMAT_ABGR2101010, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM }, + { SDL_PIXELFORMAT_RGBA64_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { SDL_PIXELFORMAT_RGB565, DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM }, + { SDL_PIXELFORMAT_ARGB1555, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM }, + { SDL_PIXELFORMAT_ARGB4444, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM } +}; + static SDL_PixelFormat D3D12_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) { - switch (dxgiFormat) { - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return SDL_PIXELFORMAT_ARGB8888; - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return SDL_PIXELFORMAT_ABGR8888; - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return SDL_PIXELFORMAT_XRGB8888; - case DXGI_FORMAT_R10G10B10A2_UNORM: - return SDL_PIXELFORMAT_ABGR2101010; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return SDL_PIXELFORMAT_RGBA64_FLOAT; - default: - return SDL_PIXELFORMAT_UNKNOWN; + for (int i = 0; i < SDL_arraysize(dxgi_format_map); i++) { + if (dxgi_format_map[i].unorm == dxgiFormat || + dxgi_format_map[i].srgb == dxgiFormat) { + return dxgi_format_map[i].sdl; + } } + return SDL_PIXELFORMAT_UNKNOWN; } static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 output_colorspace) { switch (format) { - case SDL_PIXELFORMAT_RGBA64_FLOAT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case SDL_PIXELFORMAT_ABGR2101010: - return DXGI_FORMAT_R10G10B10A2_UNORM; - case SDL_PIXELFORMAT_ARGB8888: - if (output_colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - } - return DXGI_FORMAT_B8G8R8A8_UNORM; - case SDL_PIXELFORMAT_ABGR8888: - if (output_colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - } - return DXGI_FORMAT_R8G8B8A8_UNORM; - case SDL_PIXELFORMAT_XRGB8888: - if (output_colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - } - return DXGI_FORMAT_B8G8R8X8_UNORM; case SDL_PIXELFORMAT_INDEX8: case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: @@ -355,6 +341,15 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 outpu case SDL_PIXELFORMAT_P010: return DXGI_FORMAT_P010; default: + for (int i = 0; i < SDL_arraysize(dxgi_format_map); i++) { + if (dxgi_format_map[i].sdl == format) { + if (output_colorspace == SDL_COLORSPACE_SRGB_LINEAR) { + return dxgi_format_map[i].srgb; + } else { + return dxgi_format_map[i].unorm; + } + } + } return DXGI_FORMAT_UNKNOWN; } } @@ -362,25 +357,6 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 outpu static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uint32 colorspace) { switch (format) { - case SDL_PIXELFORMAT_RGBA64_FLOAT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case SDL_PIXELFORMAT_ABGR2101010: - return DXGI_FORMAT_R10G10B10A2_UNORM; - case SDL_PIXELFORMAT_ARGB8888: - if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - } - return DXGI_FORMAT_B8G8R8A8_UNORM; - case SDL_PIXELFORMAT_ABGR8888: - if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - } - return DXGI_FORMAT_R8G8B8A8_UNORM; - case SDL_PIXELFORMAT_XRGB8888: - if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) { - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - } - return DXGI_FORMAT_B8G8R8X8_UNORM; case SDL_PIXELFORMAT_INDEX8: case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: @@ -390,7 +366,7 @@ static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uin case SDL_PIXELFORMAT_P010: // For the Y texture return DXGI_FORMAT_R16_UNORM; default: - return DXGI_FORMAT_UNKNOWN; + return SDLPixelFormatToDXGITextureFormat(format, colorspace); } } @@ -2230,7 +2206,7 @@ static bool D3D12_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, if (pitchedDesc.Format == DXGI_FORMAT_R8_UNORM) { bpp = 1; } else { - bpp = 4; + bpp = SDL_BYTESPERPIXEL(texture->format); } pitchedDesc.RowPitch = D3D12_Align(rect->w * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); @@ -2288,7 +2264,7 @@ static void D3D12_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) if (pitchedDesc.Format == DXGI_FORMAT_R8_UNORM) { bpp = 1; } else { - bpp = 4; + bpp = SDL_BYTESPERPIXEL(texture->format); } pitchedDesc.RowPitch = D3D12_Align(textureData->lockedRect.w * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); @@ -3532,17 +3508,6 @@ bool D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Proper D3D12_InvalidateCachedState(renderer); renderer->name = D3D12_RenderDriver.name; - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB8888); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ABGR8888); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB8888); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ABGR2101010); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA64_FLOAT); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21); - SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010); SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 16384); data->syncInterval = 0; @@ -3561,6 +3526,37 @@ bool D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Proper return false; } + for (int i = 0; i < SDL_arraysize(dxgi_format_map); i++) { + D3D12_FEATURE_DATA_FORMAT_SUPPORT unorm, srgb; + + unorm.Format = dxgi_format_map[i].unorm; + if (FAILED(ID3D12Device_CheckFeatureSupport(data->d3dDevice, + D3D12_FEATURE_FORMAT_SUPPORT, + &unorm, + sizeof(unorm)))) { + continue; + } + + srgb.Format = dxgi_format_map[i].srgb; + if (FAILED(ID3D12Device_CheckFeatureSupport(data->d3dDevice, + D3D12_FEATURE_FORMAT_SUPPORT, + &srgb, + sizeof(srgb)))) { + continue; + } + + if ((unorm.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D) && + (srgb.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) { + SDL_AddSupportedTextureFormat(renderer, dxgi_format_map[i].sdl); + } + } + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21); + SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010); + return true; }