mirror of
https://github.com/shadps4-emu/ext-SDL.git
synced 2025-01-07 10:50:21 +00:00
Added support for HDR10 video on Apple platforms
This commit is contained in:
parent
2039c46d2c
commit
8afba41aef
@ -76,7 +76,9 @@ static const size_t CONSTANTS_OFFSET_DECODE_BT601_LIMITED = ALIGN_CONSTANTS(16,
|
||||
static const size_t CONSTANTS_OFFSET_DECODE_BT601_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT601_LIMITED + sizeof(float) * 4 * 4);
|
||||
static const size_t CONSTANTS_OFFSET_DECODE_BT709_LIMITED = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT601_FULL + sizeof(float) * 4 * 4);
|
||||
static const size_t CONSTANTS_OFFSET_DECODE_BT709_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT709_LIMITED + sizeof(float) * 4 * 4);
|
||||
static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT709_FULL + sizeof(float) * 4 * 4;
|
||||
static const size_t CONSTANTS_OFFSET_DECODE_BT2020_LIMITED = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT709_FULL + sizeof(float) * 4 * 4);
|
||||
static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4);
|
||||
static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4;
|
||||
|
||||
typedef enum SDL_MetalVertexFunction
|
||||
{
|
||||
@ -91,6 +93,7 @@ typedef enum SDL_MetalFragmentFunction
|
||||
SDL_METAL_FRAGMENT_YUV,
|
||||
SDL_METAL_FRAGMENT_NV12,
|
||||
SDL_METAL_FRAGMENT_NV21,
|
||||
SDL_METAL_FRAGMENT_HDR10,
|
||||
SDL_METAL_FRAGMENT_COUNT,
|
||||
} SDL_MetalFragmentFunction;
|
||||
|
||||
@ -248,6 +251,8 @@ static NSString *GetFragmentFunctionName(SDL_MetalFragmentFunction function)
|
||||
return @"SDL_NV12_fragment";
|
||||
case SDL_METAL_FRAGMENT_NV21:
|
||||
return @"SDL_NV21_fragment";
|
||||
case SDL_METAL_FRAGMENT_HDR10:
|
||||
return @"SDL_HDR10_fragment";
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
@ -387,6 +392,7 @@ void MakeShaderPipelines(METAL_RenderData *data, METAL_ShaderPipelines *pipeline
|
||||
MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_YUV], "SDL YUV pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_YUV);
|
||||
MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_NV12], "SDL NV12 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_NV12);
|
||||
MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_NV21], "SDL NV21 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_NV21);
|
||||
MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_HDR10], "SDL HDR10 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_HDR10);
|
||||
}
|
||||
|
||||
static METAL_ShaderPipelines *ChooseShaderPipelines(METAL_RenderData *data, MTLPixelFormat rtformat)
|
||||
@ -551,10 +557,8 @@ size_t GetBT601ConversionMatrix( SDL_Colorspace colorspace )
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return CONSTANTS_OFFSET_DECODE_BT601_LIMITED;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return CONSTANTS_OFFSET_DECODE_BT601_FULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -567,10 +571,8 @@ size_t GetBT709ConversionMatrix(SDL_Colorspace colorspace)
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return CONSTANTS_OFFSET_DECODE_BT709_LIMITED;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return CONSTANTS_OFFSET_DECODE_BT709_FULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -582,11 +584,9 @@ size_t GetBT2020ConversionMatrix(SDL_Colorspace colorspace)
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return 0;
|
||||
break;
|
||||
return CONSTANTS_OFFSET_DECODE_BT2020_LIMITED;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return 0;
|
||||
break;
|
||||
return CONSTANTS_OFFSET_DECODE_BT2020_FULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -671,6 +671,9 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
pixfmt = MTLPixelFormatR8Unorm;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
pixfmt = MTLPixelFormatR16Unorm;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGBA64_FLOAT:
|
||||
pixfmt = MTLPixelFormatRGBA16Float;
|
||||
break;
|
||||
@ -706,8 +709,8 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
|
||||
mtltextureUv = nil;
|
||||
#if SDL_HAVE_YUV
|
||||
yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12);
|
||||
nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21);
|
||||
yuv = (texture->format == SDL_PIXELFORMAT_IYUV || texture->format == SDL_PIXELFORMAT_YV12);
|
||||
nv12 = (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21 || texture->format == SDL_PIXELFORMAT_P010);
|
||||
|
||||
if (yuv) {
|
||||
mtltexdesc.pixelFormat = MTLPixelFormatR8Unorm;
|
||||
@ -715,6 +718,10 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
mtltexdesc.height = (texture->h + 1) / 2;
|
||||
mtltexdesc.textureType = MTLTextureType2DArray;
|
||||
mtltexdesc.arrayLength = 2;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_P010) {
|
||||
mtltexdesc.pixelFormat = MTLPixelFormatRG16Unorm;
|
||||
mtltexdesc.width = (texture->w + 1) / 2;
|
||||
mtltexdesc.height = (texture->h + 1) / 2;
|
||||
} else if (nv12) {
|
||||
mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
|
||||
mtltexdesc.width = (texture->w + 1) / 2;
|
||||
@ -750,6 +757,8 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV21) {
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_P010) {
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_HDR10;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -2011,6 +2020,8 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_LIMITED, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT2020_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT2020_LIMITED, 0, 0, 10), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT2020_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT2020_FULL, 0, 0, 10), YCbCr_shader_matrix_size);
|
||||
|
||||
mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
|
||||
|
||||
@ -2139,7 +2150,7 @@ SDL_RenderDriver METAL_RenderDriver = {
|
||||
{
|
||||
"metal",
|
||||
(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
|
||||
8,
|
||||
9,
|
||||
{ SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_PIXELFORMAT_ABGR8888,
|
||||
SDL_PIXELFORMAT_RGBA64_FLOAT,
|
||||
@ -2147,7 +2158,8 @@ SDL_RenderDriver METAL_RenderDriver = {
|
||||
SDL_PIXELFORMAT_YV12,
|
||||
SDL_PIXELFORMAT_IYUV,
|
||||
SDL_PIXELFORMAT_NV12,
|
||||
SDL_PIXELFORMAT_NV21 },
|
||||
SDL_PIXELFORMAT_NV21,
|
||||
SDL_PIXELFORMAT_P010 },
|
||||
0,
|
||||
0,
|
||||
}
|
||||
|
@ -34,6 +34,19 @@ float sRGBfromLinear(float v)
|
||||
return v;
|
||||
}
|
||||
|
||||
float3 PQtoNits(float3 v)
|
||||
{
|
||||
const float c1 = 0.8359375;
|
||||
const float c2 = 18.8515625;
|
||||
const float c3 = 18.6875;
|
||||
const float oo_m1 = 1.0 / 0.1593017578125;
|
||||
const float oo_m2 = 1.0 / 78.84375;
|
||||
|
||||
float3 num = max(pow(abs(v), oo_m2) - c1, 0.0);
|
||||
float3 den = c2 - c3 * pow(abs(v), oo_m2);
|
||||
return 10000.0 * pow(abs(num / den), oo_m1);
|
||||
}
|
||||
|
||||
float4 GetOutputColor(float4 rgba, float color_scale)
|
||||
{
|
||||
float4 output;
|
||||
@ -215,3 +228,35 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
return GetOutputColorFromSRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
fragment float4 SDL_HDR10_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
constant ShaderConstants &c [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
sampler s [[sampler(0)]])
|
||||
{
|
||||
const float3x3 mat2020to709 = {
|
||||
{ 1.660496, -0.587656, -0.072840 },
|
||||
{ -0.124547, 1.132895, -0.008348 },
|
||||
{ -0.018154, -0.100597, 1.118751 }
|
||||
};
|
||||
|
||||
float3 yuv;
|
||||
yuv.x = texY.sample(s, vert.texcoord).r;
|
||||
yuv.yz = texUV.sample(s, vert.texcoord).rg;
|
||||
|
||||
float3 rgb;
|
||||
yuv += decode.offset;
|
||||
rgb.r = dot(yuv, decode.Rcoeff);
|
||||
rgb.g = dot(yuv, decode.Gcoeff);
|
||||
rgb.b = dot(yuv, decode.Bcoeff);
|
||||
|
||||
rgb = PQtoNits(rgb);
|
||||
|
||||
rgb = rgb * mat2020to709;
|
||||
|
||||
rgb = scRGBfromNits(rgb);
|
||||
|
||||
return GetOutputColorFromSCRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -815,10 +815,8 @@ static const float *SDL_GetBT601ConversionMatrix( SDL_Colorspace colorspace )
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT601_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT601_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -831,10 +829,8 @@ static const float *SDL_GetBT709ConversionMatrix(SDL_Colorspace colorspace)
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT709_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT709_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -847,10 +843,8 @@ static const float *SDL_GetBT2020ConversionMatrix(SDL_Colorspace colorspace)
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT2020_Limited_10bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT2020_Full_10bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -759,6 +759,11 @@ static SDL_bool GetTextureForVideoToolboxFrame(AVFrame *frame, SDL_Texture **tex
|
||||
case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
|
||||
format = SDL_PIXELFORMAT_NV12;
|
||||
break;
|
||||
case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
|
||||
case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
|
||||
format = SDL_PIXELFORMAT_P010;
|
||||
HDR_video = SDL_TRUE;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Unsupported texture format %c%c%c%c",
|
||||
(char)((nPixelBufferType >> 24) & 0xFF),
|
||||
|
Loading…
Reference in New Issue
Block a user