mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-06 07:54:04 +02:00
Added the concept of colorspace to the SDL renderer
This allows color operations to happen in linear space between sRGB input and sRGB output. This is currently supported on the direct3d11, direct3d12 and opengl renderers. This is a good resource on blending in linear space vs sRGB space: https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/ Also added testcolorspace to verify colorspace changes
This commit is contained in:
@@ -125,6 +125,66 @@ static const SDL_RenderDriver *render_drivers[] = {
|
||||
char SDL_renderer_magic;
|
||||
char SDL_texture_magic;
|
||||
|
||||
|
||||
void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props)
|
||||
{
|
||||
renderer->input_colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_RENDERER_CREATE_INPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB);
|
||||
renderer->output_colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB);
|
||||
renderer->colorspace_conversion = SDL_GetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_COLORSPACE_CONVERSION_BOOLEAN, SDL_TRUE);
|
||||
}
|
||||
|
||||
static float sRGBtoLinear(float v)
|
||||
{
|
||||
return v <= 0.04045f ? (v / 12.92f) : SDL_powf(((v + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
|
||||
static float sRGBfromLinear(float v)
|
||||
{
|
||||
return v <= 0.0031308f ? (v * 12.92f) : (SDL_powf(v, 1.0f / 2.4f) * 1.055f - 0.055f);
|
||||
}
|
||||
|
||||
void SDL_ConvertToLinear(SDL_Renderer *renderer, SDL_FColor *color)
|
||||
{
|
||||
if (!renderer->colorspace_conversion) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (SDL_COLORSPACETRANSFER(renderer->input_colorspace)) {
|
||||
case SDL_TRANSFER_CHARACTERISTICS_SRGB:
|
||||
color->r = sRGBtoLinear(color->r);
|
||||
color->g = sRGBtoLinear(color->g);
|
||||
color->b = sRGBtoLinear(color->b);
|
||||
break;
|
||||
case SDL_TRANSFER_CHARACTERISTICS_LINEAR:
|
||||
/* No conversion needed */
|
||||
break;
|
||||
default:
|
||||
/* Unsupported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_ConvertFromLinear(SDL_Renderer *renderer, SDL_FColor *color)
|
||||
{
|
||||
if (!renderer->colorspace_conversion) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (SDL_COLORSPACETRANSFER(renderer->input_colorspace)) {
|
||||
case SDL_TRANSFER_CHARACTERISTICS_SRGB:
|
||||
color->r = sRGBfromLinear(color->r);
|
||||
color->g = sRGBfromLinear(color->g);
|
||||
color->b = sRGBfromLinear(color->b);
|
||||
break;
|
||||
case SDL_TRANSFER_CHARACTERISTICS_LINEAR:
|
||||
/* No conversion needed */
|
||||
break;
|
||||
default:
|
||||
/* Unsupported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_INLINE void DebugLogRenderCommands(const SDL_RenderCommand *cmd)
|
||||
{
|
||||
#if 0
|
||||
@@ -1115,6 +1175,19 @@ static SDL_ScaleMode SDL_GetScaleMode(void)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Colorspace SDL_GetDefaultTextureColorspace(Uint32 format)
|
||||
{
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
return SDL_COLORSPACE_BT709_FULL;
|
||||
} else if (SDL_ISPIXELFORMAT_FLOAT(format)) {
|
||||
return SDL_COLORSPACE_SCRGB;
|
||||
} else if (SDL_ISPIXELFORMAT_10BIT(format)) {
|
||||
return SDL_COLORSPACE_HDR10;
|
||||
} else {
|
||||
return SDL_COLORSPACE_SRGB;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_PropertiesID props)
|
||||
{
|
||||
SDL_Texture *texture;
|
||||
@@ -1122,6 +1195,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
||||
int access = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||
int w = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, 0);
|
||||
int h = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, 0);
|
||||
Uint32 default_colorspace;
|
||||
SDL_bool texture_is_fourcc_and_target;
|
||||
|
||||
CHECK_RENDERER_MAGIC(renderer, NULL);
|
||||
@@ -1148,11 +1222,15 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
||||
SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
default_colorspace = SDL_GetDefaultTextureColorspace(format);
|
||||
|
||||
texture = (SDL_Texture *)SDL_calloc(1, sizeof(*texture));
|
||||
if (!texture) {
|
||||
return NULL;
|
||||
}
|
||||
texture->magic = &SDL_texture_magic;
|
||||
texture->colorspace = (Uint32)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, default_colorspace);
|
||||
texture->format = format;
|
||||
texture->access = access;
|
||||
texture->w = w;
|
||||
@@ -1176,9 +1254,9 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
||||
renderer->textures = texture;
|
||||
|
||||
/* FOURCC format cannot be used directly by renderer back-ends for target texture */
|
||||
texture_is_fourcc_and_target = (access == SDL_TEXTUREACCESS_TARGET && SDL_ISPIXELFORMAT_FOURCC(texture->format));
|
||||
texture_is_fourcc_and_target = (access == SDL_TEXTUREACCESS_TARGET && SDL_ISPIXELFORMAT_FOURCC(format));
|
||||
|
||||
if (texture_is_fourcc_and_target == SDL_FALSE && IsSupportedFormat(renderer, format)) {
|
||||
if (!texture_is_fourcc_and_target && IsSupportedFormat(renderer, format)) {
|
||||
if (renderer->CreateTexture(renderer, texture, props) < 0) {
|
||||
SDL_DestroyTexture(texture);
|
||||
return NULL;
|
||||
@@ -1186,7 +1264,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
||||
} else {
|
||||
int closest_format;
|
||||
|
||||
if (texture_is_fourcc_and_target == SDL_FALSE) {
|
||||
if (!texture_is_fourcc_and_target) {
|
||||
closest_format = GetClosestSupportedFormat(renderer, format);
|
||||
} else {
|
||||
closest_format = renderer->info.texture_formats[0];
|
||||
@@ -1255,6 +1333,8 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
||||
int i;
|
||||
Uint32 format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
SDL_Texture *texture;
|
||||
SDL_PropertiesID props;
|
||||
Uint32 default_colorspace, colorspace;
|
||||
|
||||
CHECK_RENDERER_MAGIC(renderer, NULL);
|
||||
|
||||
@@ -1320,8 +1400,16 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
||||
}
|
||||
}
|
||||
|
||||
texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
|
||||
surface->w, surface->h);
|
||||
default_colorspace = SDL_GetDefaultTextureColorspace(format);
|
||||
colorspace = (Uint32)SDL_GetNumberProperty(SDL_GetSurfaceProperties(surface), SDL_PROP_SURFACE_COLORSPACE_NUMBER, default_colorspace);
|
||||
|
||||
props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, colorspace);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, format);
|
||||
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);
|
||||
texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||
if (!texture) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1441,6 +1529,7 @@ int SDL_SetTextureColorModFloat(SDL_Texture *texture, float r, float g, float b)
|
||||
texture->color.r = r;
|
||||
texture->color.g = g;
|
||||
texture->color.b = b;
|
||||
SDL_ConvertToLinear(texture->renderer, &texture->color);
|
||||
if (texture->native) {
|
||||
return SDL_SetTextureColorModFloat(texture->native, r, g, b);
|
||||
}
|
||||
@@ -1469,16 +1558,21 @@ int SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b)
|
||||
|
||||
int SDL_GetTextureColorModFloat(SDL_Texture *texture, float *r, float *g, float *b)
|
||||
{
|
||||
SDL_FColor color;
|
||||
|
||||
CHECK_TEXTURE_MAGIC(texture, -1);
|
||||
|
||||
color = texture->color;
|
||||
SDL_ConvertFromLinear(texture->renderer, &color);
|
||||
|
||||
if (r) {
|
||||
*r = texture->color.r;
|
||||
*r = color.r;
|
||||
}
|
||||
if (g) {
|
||||
*g = texture->color.g;
|
||||
*g = color.g;
|
||||
}
|
||||
if (b) {
|
||||
*b = texture->color.b;
|
||||
*b = color.b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2689,6 +2783,7 @@ int SDL_SetRenderDrawColorFloat(SDL_Renderer *renderer, float r, float g, float
|
||||
renderer->color.g = g;
|
||||
renderer->color.b = b;
|
||||
renderer->color.a = a;
|
||||
SDL_ConvertToLinear(renderer, &renderer->color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2717,19 +2812,24 @@ int SDL_GetRenderDrawColor(SDL_Renderer *renderer, Uint8 *r, Uint8 *g, Uint8 *b,
|
||||
|
||||
int SDL_GetRenderDrawColorFloat(SDL_Renderer *renderer, float *r, float *g, float *b, float *a)
|
||||
{
|
||||
SDL_FColor color;
|
||||
|
||||
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||
|
||||
color = renderer->color;
|
||||
SDL_ConvertFromLinear(renderer, &color);
|
||||
|
||||
if (r) {
|
||||
*r = renderer->color.r;
|
||||
*r = color.r;
|
||||
}
|
||||
if (g) {
|
||||
*g = renderer->color.g;
|
||||
*g = color.g;
|
||||
}
|
||||
if (b) {
|
||||
*b = renderer->color.b;
|
||||
*b = color.b;
|
||||
}
|
||||
if (a) {
|
||||
*a = renderer->color.a;
|
||||
*a = color.a;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ typedef struct SDL_RenderViewState
|
||||
struct SDL_Texture
|
||||
{
|
||||
const void *magic;
|
||||
SDL_Colorspace colorspace; /**< The colorspace of the texture */
|
||||
Uint32 format; /**< The pixel format of the texture */
|
||||
int access; /**< SDL_TextureAccess */
|
||||
int w; /**< The width of the texture */
|
||||
@@ -249,6 +250,10 @@ struct SDL_Renderer
|
||||
SDL_Texture *target;
|
||||
SDL_Mutex *target_mutex;
|
||||
|
||||
SDL_Colorspace input_colorspace;
|
||||
SDL_Colorspace output_colorspace;
|
||||
SDL_bool colorspace_conversion;
|
||||
|
||||
SDL_FColor color; /**< Color for drawing operations values */
|
||||
SDL_BlendMode blendMode; /**< The drawing blend mode */
|
||||
|
||||
@@ -294,6 +299,13 @@ extern SDL_RenderDriver PSP_RenderDriver;
|
||||
extern SDL_RenderDriver SW_RenderDriver;
|
||||
extern SDL_RenderDriver VITA_GXM_RenderDriver;
|
||||
|
||||
/* Setup colorspace conversion */
|
||||
extern void SDL_SetupRendererColorspace(SDL_Renderer *renderer, SDL_PropertiesID props);
|
||||
|
||||
/* Colorspace conversion functions */
|
||||
extern void SDL_ConvertToLinear(SDL_Renderer *renderer, SDL_FColor *color);
|
||||
extern void SDL_ConvertFromLinear(SDL_Renderer *renderer, SDL_FColor *color);
|
||||
|
||||
/* Blend mode functions */
|
||||
extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode);
|
||||
extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode);
|
||||
|
||||
@@ -198,20 +198,28 @@ Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat)
|
||||
{
|
||||
switch (dxgiFormat) {
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
return SDL_PIXELFORMAT_ARGB8888;
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
return SDL_PIXELFORMAT_XRGB8888;
|
||||
default:
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 sdlFormat)
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
|
||||
{
|
||||
switch (sdlFormat) {
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
@@ -224,12 +232,18 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 sdlFormat)
|
||||
}
|
||||
}
|
||||
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 sdlFormat)
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
|
||||
{
|
||||
switch (sdlFormat) {
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
@@ -988,9 +1002,17 @@ static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
|
||||
}
|
||||
|
||||
/* Create a render target view of the swap chain back buffer. */
|
||||
D3D11_RENDER_TARGET_VIEW_DESC desc;
|
||||
SDL_zero(desc);
|
||||
if (renderer->colorspace_conversion && renderer->output_colorspace == SDL_COLORSPACE_SRGB) {
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
} else {
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
result = ID3D11Device_CreateRenderTargetView(data->d3dDevice,
|
||||
(ID3D11Resource *)backBuffer,
|
||||
NULL,
|
||||
&desc,
|
||||
&data->mainRenderTargetView);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device::CreateRenderTargetView"), result);
|
||||
@@ -1083,7 +1105,7 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
|
||||
D3D11_TextureData *textureData;
|
||||
HRESULT result;
|
||||
DXGI_FORMAT textureFormat = SDLPixelFormatToDXGITextureFormat(texture->format);
|
||||
DXGI_FORMAT textureFormat = SDLPixelFormatToDXGITextureFormat(texture->format, texture->colorspace, renderer->colorspace_conversion);
|
||||
D3D11_TEXTURE2D_DESC textureDesc;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
|
||||
|
||||
@@ -1182,7 +1204,7 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
}
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
SDL_zero(resourceViewDesc);
|
||||
resourceViewDesc.Format = SDLPixelFormatToDXGIMainResourceViewFormat(texture->format);
|
||||
resourceViewDesc.Format = SDLPixelFormatToDXGIMainResourceViewFormat(texture->format, texture->colorspace, renderer->colorspace_conversion);
|
||||
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
resourceViewDesc.Texture2D.MostDetailedMip = 0;
|
||||
resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
|
||||
@@ -2441,6 +2463,8 @@ SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
data->identity = MatrixIdentity();
|
||||
|
||||
renderer->WindowEvent = D3D11_WindowEvent;
|
||||
|
||||
@@ -273,20 +273,28 @@ Uint32 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_B8G8R8X8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
return SDL_PIXELFORMAT_XRGB8888;
|
||||
default:
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 sdlFormat)
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
|
||||
{
|
||||
switch (sdlFormat) {
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
@@ -299,12 +307,18 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 sdlFormat)
|
||||
}
|
||||
}
|
||||
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 sdlFormat)
|
||||
static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uint32 colorspace, SDL_bool colorspace_conversion)
|
||||
{
|
||||
switch (sdlFormat) {
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
|
||||
}
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
@@ -1340,7 +1354,11 @@ static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
|
||||
#endif
|
||||
|
||||
SDL_zero(rtvDesc);
|
||||
rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
if (renderer->colorspace_conversion && renderer->output_colorspace == SDL_COLORSPACE_SRGB) {
|
||||
rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
} else {
|
||||
rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
|
||||
SDL_zero(rtvDescriptor);
|
||||
@@ -1450,7 +1468,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata;
|
||||
D3D12_TextureData *textureData;
|
||||
HRESULT result;
|
||||
DXGI_FORMAT textureFormat = SDLPixelFormatToDXGITextureFormat(texture->format);
|
||||
DXGI_FORMAT textureFormat = SDLPixelFormatToDXGITextureFormat(texture->format, texture->colorspace, renderer->colorspace_conversion);
|
||||
D3D12_RESOURCE_DESC textureDesc;
|
||||
D3D12_HEAP_PROPERTIES heapProps;
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
|
||||
@@ -1563,7 +1581,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
SDL_zero(resourceViewDesc);
|
||||
resourceViewDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
resourceViewDesc.Format = SDLPixelFormatToDXGIMainResourceViewFormat(texture->format);
|
||||
resourceViewDesc.Format = SDLPixelFormatToDXGIMainResourceViewFormat(texture->format, texture->colorspace, renderer->colorspace_conversion);
|
||||
resourceViewDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
|
||||
|
||||
@@ -2985,6 +3003,8 @@ SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
data->identity = MatrixIdentity();
|
||||
|
||||
renderer->WindowEvent = D3D12_WindowEvent;
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html
|
||||
*/
|
||||
|
||||
static const float inv255f = 1.0f / 255.0f;
|
||||
|
||||
typedef struct GL_FBOList GL_FBOList;
|
||||
|
||||
struct GL_FBOList
|
||||
@@ -403,19 +401,27 @@ static SDL_bool GL_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blend
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
|
||||
static SDL_bool convert_format(Uint32 pixel_format, Uint32 colorspace, SDL_bool colorspace_conversion,
|
||||
GLint *internalFormat, GLenum *format, GLenum *type)
|
||||
{
|
||||
switch (pixel_format) {
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
case SDL_PIXELFORMAT_XRGB8888:
|
||||
*internalFormat = GL_RGBA8;
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
*internalFormat = GL_SRGB8_ALPHA8;
|
||||
} else {
|
||||
*internalFormat = GL_RGBA8;
|
||||
}
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ABGR8888:
|
||||
case SDL_PIXELFORMAT_XBGR8888:
|
||||
*internalFormat = GL_RGBA8;
|
||||
if (colorspace_conversion && colorspace == SDL_COLORSPACE_SRGB) {
|
||||
*internalFormat = GL_SRGB8_ALPHA8;
|
||||
} else {
|
||||
*internalFormat = GL_RGBA8;
|
||||
}
|
||||
*format = GL_RGBA;
|
||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
break;
|
||||
@@ -460,8 +466,8 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
|
||||
return SDL_SetError("Render targets not supported by OpenGL");
|
||||
}
|
||||
|
||||
if (!convert_format(renderdata, texture->format, &internalFormat,
|
||||
&format, &type)) {
|
||||
if (!convert_format(texture->format, texture->colorspace, renderer->colorspace_conversion,
|
||||
&internalFormat, &format, &type)) {
|
||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
||||
SDL_GetPixelFormatName(texture->format));
|
||||
}
|
||||
@@ -1475,7 +1481,8 @@ static int GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
if (!convert_format(data, temp_format, &internalFormat, &format, &type)) {
|
||||
if (!convert_format(temp_format, renderer->input_colorspace, renderer->colorspace_conversion,
|
||||
&internalFormat, &format, &type)) {
|
||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
||||
SDL_GetPixelFormatName(temp_format));
|
||||
}
|
||||
@@ -1709,6 +1716,8 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
||||
goto error;
|
||||
}
|
||||
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
renderer->WindowEvent = GL_WindowEvent;
|
||||
renderer->SupportsBlendMode = GL_SupportsBlendMode;
|
||||
renderer->CreateTexture = GL_CreateTexture;
|
||||
@@ -1910,6 +1919,9 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
||||
data->glDisable(data->textype);
|
||||
data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (renderer->colorspace_conversion && renderer->output_colorspace == SDL_COLORSPACE_SRGB) {
|
||||
data->glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
/* This ended up causing video discrepancies between OpenGL and Direct3D */
|
||||
/* data->glEnable(GL_LINE_SMOOTH); */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user