From e74171b1ae93c8505d17212ec88cfadb7d7c15a9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 4 Feb 2024 22:19:28 -0800
Subject: [PATCH] Added support for HDR10 video playback on direct3d11
Fixes https://github.com/libsdl-org/SDL/issues/8053
---
include/SDL3/SDL_pixels.h | 24 +-
.../direct3d11/D3D11_PixelShader_HDR10.h | 515 ++++++++++++++++++
.../direct3d11/D3D11_PixelShader_HDR10.hlsl | 92 ++++
src/render/direct3d11/SDL_render_d3d11.c | 90 ++-
src/render/direct3d11/SDL_shaders_d3d11.c | 5 +
src/render/direct3d11/SDL_shaders_d3d11.h | 1 +
src/render/direct3d11/compile_shaders.bat | 1 +
src/video/SDL_pixels.c | 51 +-
test/testffmpeg.c | 55 +-
9 files changed, 809 insertions(+), 25 deletions(-)
create mode 100755 src/render/direct3d11/D3D11_PixelShader_HDR10.h
create mode 100644 src/render/direct3d11/D3D11_PixelShader_HDR10.hlsl
diff --git a/include/SDL3/SDL_pixels.h b/include/SDL3/SDL_pixels.h
index de695f81e6cf..d893a49fe7a9 100644
--- a/include/SDL3/SDL_pixels.h
+++ b/include/SDL3/SDL_pixels.h
@@ -165,7 +165,9 @@ typedef enum
(SDL_ISPIXELFORMAT_FOURCC(X) ? \
((((X) == SDL_PIXELFORMAT_YUY2) || \
((X) == SDL_PIXELFORMAT_UYVY) || \
- ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
+ ((X) == SDL_PIXELFORMAT_YVYU) || \
+ ((X) == SDL_PIXELFORMAT_P010) || \
+ ((X) == SDL_PIXELFORMAT_P016)) ? 2 : 1) : (((X) >> 0) & 0xFF))
#define SDL_ISPIXELFORMAT_INDEXED(format) \
(!SDL_ISPIXELFORMAT_FOURCC(format) && \
@@ -414,6 +416,10 @@ typedef enum
SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'),
SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */
SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'),
+ SDL_PIXELFORMAT_P010 = /**< Planar mode: Y + U/V interleaved (2 planes) */
+ SDL_DEFINE_PIXELFOURCC('P', '0', '1', '0'),
+ SDL_PIXELFORMAT_P016 = /**< Planar mode: Y + U/V interleaved (2 planes) */
+ SDL_DEFINE_PIXELFOURCC('P', '0', '1', '6'),
SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */
SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ')
} SDL_PixelFormatEnum;
@@ -631,6 +637,22 @@ typedef enum
SDL_MATRIX_COEFFICIENTS_BT709,
SDL_CHROMA_LOCATION_LEFT),
+ SDL_COLORSPACE_BT2020_LIMITED = /**< Equivalent to DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 */
+ SDL_DEFINE_COLORSPACE(SDL_COLOR_TYPE_YCBCR,
+ SDL_COLOR_RANGE_LIMITED,
+ SDL_COLOR_PRIMARIES_BT2020,
+ SDL_TRANSFER_CHARACTERISTICS_PQ,
+ SDL_MATRIX_COEFFICIENTS_BT2020_NCL,
+ SDL_CHROMA_LOCATION_LEFT),
+
+ SDL_COLORSPACE_BT2020_FULL = /**< Equivalent to DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 */
+ SDL_DEFINE_COLORSPACE(SDL_COLOR_TYPE_YCBCR,
+ SDL_COLOR_RANGE_FULL,
+ SDL_COLOR_PRIMARIES_BT2020,
+ SDL_TRANSFER_CHARACTERISTICS_PQ,
+ SDL_MATRIX_COEFFICIENTS_BT2020_NCL,
+ SDL_CHROMA_LOCATION_LEFT),
+
/* The default colorspace for RGB surfaces if no colorspace is specified */
SDL_COLORSPACE_RGB_DEFAULT = SDL_COLORSPACE_SRGB,
diff --git a/src/render/direct3d11/D3D11_PixelShader_HDR10.h b/src/render/direct3d11/D3D11_PixelShader_HDR10.h
new file mode 100755
index 000000000000..afd6772f6b9d
--- /dev/null
+++ b/src/render/direct3d11/D3D11_PixelShader_HDR10.h
@@ -0,0 +1,515 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer Constants
+// {
+//
+// float4 Yoffset; // Offset: 0 Size: 16
+// float4 Rcoeff; // Offset: 16 Size: 16
+// float4 Gcoeff; // Offset: 32 Size: 16
+// float4 Bcoeff; // Offset: 48 Size: 16
+// float scRGB_output; // Offset: 64 Size: 4
+// float SDR_whitelevel; // Offset: 68 Size: 4 [unused]
+// float HDR_whitelevel; // Offset: 72 Size: 4
+// float maxCLL; // Offset: 76 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// theSampler sampler NA NA s0 1
+// theTextureY texture float4 2d t0 1
+// theTextureUV texture float4 2d t1 1
+// Constants cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// TEXCOORD 0 xy 1 NONE float xy
+// COLOR 0 xyzw 2 NONE float xyzw
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[5], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_resource_texture2d (float,float,float,float) t1
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v2.xyzw
+dcl_output o0.xyzw
+dcl_temps 4
+sample_indexable(texture2d)(float,float,float,float) r0.x, v1.xyxx, t0.xyzw, s0
+sample_indexable(texture2d)(float,float,float,float) r0.yz, v1.xyxx, t1.zxyw, s0
+add r0.xyz, r0.xyzx, cb0[0].xyzx
+dp3 r1.x, r0.xyzx, cb0[1].xyzx
+dp3 r1.y, r0.xyzx, cb0[2].xyzx
+dp3 r1.z, r0.xyzx, cb0[3].xyzx
+log r0.xyz, |r1.xyzx|
+mul r0.xyz, r0.xyzx, l(0.012683, 0.012683, 0.012683, 0.000000)
+exp r0.xyz, r0.xyzx
+add r1.xyz, r0.xyzx, l(-0.835938, -0.835938, -0.835938, 0.000000)
+max r1.xyz, r1.xyzx, l(0.000000, 0.000000, 0.000000, 0.000000)
+mad r0.xyz, -r0.xyzx, l(18.687500, 18.687500, 18.687500, 0.000000), l(18.851562, 18.851562, 18.851562, 0.000000)
+div r0.xyz, r1.xyzx, r0.xyzx
+log r0.xyz, |r0.xyzx|
+mul r0.xyz, r0.xyzx, l(6.277395, 6.277395, 6.277395, 0.000000)
+exp r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(10000.000000, 10000.000000, 10000.000000, 0.000000)
+dp3 r1.x, l(1.660496, -0.587656, -0.072840, 0.000000), r0.xyzx
+dp3 r1.y, l(-0.124547, 1.132895, -0.008348, 0.000000), r0.xyzx
+dp3 r1.z, l(-0.018154, -0.100597, 1.118751, 0.000000), r0.xyzx
+div r0.xyz, r1.xyzx, cb0[4].wwww
+mul r0.xyz, r0.xyzx, cb0[4].zzzz
+mul r1.xyz, r0.xyzx, l(0.012500, 0.012500, 0.012500, 0.000000)
+ne r0.w, l(0.000000, 0.000000, 0.000000, 0.000000), cb0[4].x
+if_z r0.w
+ ge r2.xyz, l(0.250464, 0.250464, 0.250464, 0.000000), r0.xyzx
+ mul r0.xyz, r0.xyzx, l(0.161500, 0.161500, 0.161500, 0.000000)
+ log r3.xyz, |r1.xyzx|
+ mul r3.xyz, r3.xyzx, l(0.416667, 0.416667, 0.416667, 0.000000)
+ exp r3.xyz, r3.xyzx
+ mad r3.xyz, r3.xyzx, l(1.055000, 1.055000, 1.055000, 0.000000), l(-0.055000, -0.055000, -0.055000, 0.000000)
+ movc_sat r1.xyz, r2.xyzx, r0.xyzx, r3.xyzx
+endif
+mov r1.w, l(1.000000)
+mul o0.xyzw, r1.xyzw, v2.xyzw
+ret
+// Approximately 36 instruction slots used
+#endif
+
+const BYTE g_main[] =
+{
+ 68, 88, 66, 67, 110, 205,
+ 144, 108, 2, 231, 108, 209,
+ 128, 137, 101, 210, 29, 69,
+ 41, 122, 1, 0, 0, 0,
+ 184, 9, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 80, 3, 0, 0, 196, 3,
+ 0, 0, 248, 3, 0, 0,
+ 28, 9, 0, 0, 82, 68,
+ 69, 70, 20, 3, 0, 0,
+ 1, 0, 0, 0, 236, 0,
+ 0, 0, 4, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 255, 255, 0, 1, 0, 0,
+ 233, 2, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 188, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 199, 0, 0, 0,
+ 2, 0, 0, 0, 5, 0,
+ 0, 0, 4, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 13, 0, 0, 0, 211, 0,
+ 0, 0, 2, 0, 0, 0,
+ 5, 0, 0, 0, 4, 0,
+ 0, 0, 255, 255, 255, 255,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0,
+ 224, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 116, 104, 101, 83,
+ 97, 109, 112, 108, 101, 114,
+ 0, 116, 104, 101, 84, 101,
+ 120, 116, 117, 114, 101, 89,
+ 0, 116, 104, 101, 84, 101,
+ 120, 116, 117, 114, 101, 85,
+ 86, 0, 67, 111, 110, 115,
+ 116, 97, 110, 116, 115, 0,
+ 171, 171, 224, 0, 0, 0,
+ 8, 0, 0, 0, 4, 1,
+ 0, 0, 80, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 2, 0, 0,
+ 0, 0, 0, 0, 16, 0,
+ 0, 0, 2, 0, 0, 0,
+ 84, 2, 0, 0, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 120, 2, 0, 0, 16, 0,
+ 0, 0, 16, 0, 0, 0,
+ 2, 0, 0, 0, 84, 2,
+ 0, 0, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 127, 2,
+ 0, 0, 32, 0, 0, 0,
+ 16, 0, 0, 0, 2, 0,
+ 0, 0, 84, 2, 0, 0,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 134, 2, 0, 0,
+ 48, 0, 0, 0, 16, 0,
+ 0, 0, 2, 0, 0, 0,
+ 84, 2, 0, 0, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 141, 2, 0, 0, 64, 0,
+ 0, 0, 4, 0, 0, 0,
+ 2, 0, 0, 0, 160, 2,
+ 0, 0, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 196, 2,
+ 0, 0, 68, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0,
+ 0, 0, 160, 2, 0, 0,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 211, 2, 0, 0,
+ 72, 0, 0, 0, 4, 0,
+ 0, 0, 2, 0, 0, 0,
+ 160, 2, 0, 0, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 226, 2, 0, 0, 76, 0,
+ 0, 0, 4, 0, 0, 0,
+ 2, 0, 0, 0, 160, 2,
+ 0, 0, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 89, 111,
+ 102, 102, 115, 101, 116, 0,
+ 102, 108, 111, 97, 116, 52,
+ 0, 171, 1, 0, 3, 0,
+ 1, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 76, 2,
+ 0, 0, 82, 99, 111, 101,
+ 102, 102, 0, 71, 99, 111,
+ 101, 102, 102, 0, 66, 99,
+ 111, 101, 102, 102, 0, 115,
+ 99, 82, 71, 66, 95, 111,
+ 117, 116, 112, 117, 116, 0,
+ 102, 108, 111, 97, 116, 0,
+ 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 154, 2, 0, 0,
+ 83, 68, 82, 95, 119, 104,
+ 105, 116, 101, 108, 101, 118,
+ 101, 108, 0, 72, 68, 82,
+ 95, 119, 104, 105, 116, 101,
+ 108, 101, 118, 101, 108, 0,
+ 109, 97, 120, 67, 76, 76,
+ 0, 77, 105, 99, 114, 111,
+ 115, 111, 102, 116, 32, 40,
+ 82, 41, 32, 72, 76, 83,
+ 76, 32, 83, 104, 97, 100,
+ 101, 114, 32, 67, 111, 109,
+ 112, 105, 108, 101, 114, 32,
+ 49, 48, 46, 49, 0, 171,
+ 171, 171, 73, 83, 71, 78,
+ 108, 0, 0, 0, 3, 0,
+ 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0,
+ 92, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 1, 0,
+ 0, 0, 3, 3, 0, 0,
+ 101, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 2, 0,
+ 0, 0, 15, 15, 0, 0,
+ 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0,
+ 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 67, 79, 76,
+ 79, 82, 0, 171, 79, 83,
+ 71, 78, 44, 0, 0, 0,
+ 1, 0, 0, 0, 8, 0,
+ 0, 0, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0,
+ 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0,
+ 171, 171, 83, 72, 69, 88,
+ 28, 5, 0, 0, 80, 0,
+ 0, 0, 71, 1, 0, 0,
+ 106, 8, 0, 1, 89, 0,
+ 0, 4, 70, 142, 32, 0,
+ 0, 0, 0, 0, 5, 0,
+ 0, 0, 90, 0, 0, 3,
+ 0, 96, 16, 0, 0, 0,
+ 0, 0, 88, 24, 0, 4,
+ 0, 112, 16, 0, 0, 0,
+ 0, 0, 85, 85, 0, 0,
+ 88, 24, 0, 4, 0, 112,
+ 16, 0, 1, 0, 0, 0,
+ 85, 85, 0, 0, 98, 16,
+ 0, 3, 50, 16, 16, 0,
+ 1, 0, 0, 0, 98, 16,
+ 0, 3, 242, 16, 16, 0,
+ 2, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0,
+ 0, 0, 0, 0, 104, 0,
+ 0, 2, 4, 0, 0, 0,
+ 69, 0, 0, 139, 194, 0,
+ 0, 128, 67, 85, 21, 0,
+ 18, 0, 16, 0, 0, 0,
+ 0, 0, 70, 16, 16, 0,
+ 1, 0, 0, 0, 70, 126,
+ 16, 0, 0, 0, 0, 0,
+ 0, 96, 16, 0, 0, 0,
+ 0, 0, 69, 0, 0, 139,
+ 194, 0, 0, 128, 67, 85,
+ 21, 0, 98, 0, 16, 0,
+ 0, 0, 0, 0, 70, 16,
+ 16, 0, 1, 0, 0, 0,
+ 38, 125, 16, 0, 1, 0,
+ 0, 0, 0, 96, 16, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 8, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 70, 130, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 8, 18, 0,
+ 16, 0, 1, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 70, 130, 32, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 16, 0, 0, 8,
+ 34, 0, 16, 0, 1, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 70, 130,
+ 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 16, 0,
+ 0, 8, 66, 0, 16, 0,
+ 1, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 70, 130, 32, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0,
+ 47, 0, 0, 6, 114, 0,
+ 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 128, 129, 0,
+ 0, 0, 1, 0, 0, 0,
+ 56, 0, 0, 10, 114, 0,
+ 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0,
+ 172, 205, 79, 60, 172, 205,
+ 79, 60, 172, 205, 79, 60,
+ 0, 0, 0, 0, 25, 0,
+ 0, 5, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 114, 0,
+ 16, 0, 1, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0,
+ 0, 0, 86, 191, 0, 0,
+ 86, 191, 0, 0, 86, 191,
+ 0, 0, 0, 0, 52, 0,
+ 0, 10, 114, 0, 16, 0,
+ 1, 0, 0, 0, 70, 2,
+ 16, 0, 1, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 0, 0, 16,
+ 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 128,
+ 65, 0, 0, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0,
+ 0, 128, 149, 65, 0, 128,
+ 149, 65, 0, 128, 149, 65,
+ 0, 0, 0, 0, 2, 64,
+ 0, 0, 0, 208, 150, 65,
+ 0, 208, 150, 65, 0, 208,
+ 150, 65, 0, 0, 0, 0,
+ 14, 0, 0, 7, 114, 0,
+ 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 1, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 47, 0,
+ 0, 6, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 128, 129, 0, 0, 0,
+ 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 107, 224,
+ 200, 64, 107, 224, 200, 64,
+ 107, 224, 200, 64, 0, 0,
+ 0, 0, 25, 0, 0, 5,
+ 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 64,
+ 28, 70, 0, 64, 28, 70,
+ 0, 64, 28, 70, 0, 0,
+ 0, 0, 16, 0, 0, 10,
+ 18, 0, 16, 0, 1, 0,
+ 0, 0, 2, 64, 0, 0,
+ 34, 139, 212, 63, 160, 112,
+ 22, 191, 35, 45, 149, 189,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 16, 0, 0, 10, 34, 0,
+ 16, 0, 1, 0, 0, 0,
+ 2, 64, 0, 0, 127, 18,
+ 255, 189, 180, 2, 145, 63,
+ 13, 198, 8, 188, 0, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 16, 0,
+ 0, 10, 66, 0, 16, 0,
+ 1, 0, 0, 0, 2, 64,
+ 0, 0, 179, 183, 148, 188,
+ 205, 5, 206, 189, 60, 51,
+ 143, 63, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 14, 0, 0, 8,
+ 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0,
+ 1, 0, 0, 0, 246, 143,
+ 32, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 56, 0,
+ 0, 8, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 166, 138, 32, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 56, 0, 0, 10, 114, 0,
+ 16, 0, 1, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0,
+ 205, 204, 76, 60, 205, 204,
+ 76, 60, 205, 204, 76, 60,
+ 0, 0, 0, 0, 57, 0,
+ 0, 11, 130, 0, 16, 0,
+ 0, 0, 0, 0, 2, 64,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 10, 128, 32, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 31, 0, 0, 3, 58, 0,
+ 16, 0, 0, 0, 0, 0,
+ 29, 0, 0, 10, 114, 0,
+ 16, 0, 2, 0, 0, 0,
+ 2, 64, 0, 0, 209, 60,
+ 128, 62, 209, 60, 128, 62,
+ 209, 60, 128, 62, 0, 0,
+ 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 66, 96,
+ 37, 62, 66, 96, 37, 62,
+ 66, 96, 37, 62, 0, 0,
+ 0, 0, 47, 0, 0, 6,
+ 114, 0, 16, 0, 3, 0,
+ 0, 0, 70, 2, 16, 128,
+ 129, 0, 0, 0, 1, 0,
+ 0, 0, 56, 0, 0, 10,
+ 114, 0, 16, 0, 3, 0,
+ 0, 0, 70, 2, 16, 0,
+ 3, 0, 0, 0, 2, 64,
+ 0, 0, 85, 85, 213, 62,
+ 85, 85, 213, 62, 85, 85,
+ 213, 62, 0, 0, 0, 0,
+ 25, 0, 0, 5, 114, 0,
+ 16, 0, 3, 0, 0, 0,
+ 70, 2, 16, 0, 3, 0,
+ 0, 0, 50, 0, 0, 15,
+ 114, 0, 16, 0, 3, 0,
+ 0, 0, 70, 2, 16, 0,
+ 3, 0, 0, 0, 2, 64,
+ 0, 0, 61, 10, 135, 63,
+ 61, 10, 135, 63, 61, 10,
+ 135, 63, 0, 0, 0, 0,
+ 2, 64, 0, 0, 174, 71,
+ 97, 189, 174, 71, 97, 189,
+ 174, 71, 97, 189, 0, 0,
+ 0, 0, 55, 32, 0, 9,
+ 114, 0, 16, 0, 1, 0,
+ 0, 0, 70, 2, 16, 0,
+ 2, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 3, 0,
+ 0, 0, 21, 0, 0, 1,
+ 54, 0, 0, 5, 130, 0,
+ 16, 0, 1, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0,
+ 128, 63, 56, 0, 0, 7,
+ 242, 32, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0,
+ 1, 0, 0, 0, 70, 30,
+ 16, 0, 2, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84,
+ 65, 84, 148, 0, 0, 0,
+ 36, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 28, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
diff --git a/src/render/direct3d11/D3D11_PixelShader_HDR10.hlsl b/src/render/direct3d11/D3D11_PixelShader_HDR10.hlsl
new file mode 100644
index 000000000000..0f0b6ece7479
--- /dev/null
+++ b/src/render/direct3d11/D3D11_PixelShader_HDR10.hlsl
@@ -0,0 +1,92 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+ float4 pos : SV_POSITION;
+ float2 tex : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+cbuffer Constants : register(b0)
+{
+ float4 Yoffset;
+ float4 Rcoeff;
+ float4 Gcoeff;
+ float4 Bcoeff;
+
+ float scRGB_output;
+ float SDR_whitelevel;
+ float HDR_whitelevel;
+ float maxCLL;
+};
+
+
+float3 scRGBfromNits(float3 v)
+{
+ return v / 80.0;
+}
+
+float sRGBfromLinear(float v)
+{
+ if (v <= 0.0031308) {
+ v = (v * 12.92);
+ } else {
+ v = (pow(abs(v), 1.0 / 2.4) * 1.055 - 0.055);
+ }
+ 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 main(PixelShaderInput input) : SV_TARGET
+{
+ 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 = theTextureY.Sample(theSampler, input.tex).r;
+ yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg;
+
+ float3 rgb;
+ yuv += Yoffset.xyz;
+ rgb.r = dot(yuv, Rcoeff.xyz);
+ rgb.g = dot(yuv, Gcoeff.xyz);
+ rgb.b = dot(yuv, Bcoeff.xyz);
+
+ rgb = PQtoNits(rgb);
+
+ rgb = mul(mat2020to709, rgb);
+
+ rgb = (rgb / maxCLL) * HDR_whitelevel;
+
+ rgb = scRGBfromNits(rgb);
+
+ if (!scRGB_output) {
+ rgb.r = sRGBfromLinear(rgb.r);
+ rgb.g = sRGBfromLinear(rgb.g);
+ rgb.b = sRGBfromLinear(rgb.b);
+ rgb.rgb = clamp(rgb.rgb, 0.0, 1.0);
+ }
+
+ float4 Output;
+ Output.rgb = rgb.rgb;
+ Output.a = 1.0f;
+
+ return Output * input.color;
+}
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index 86de08e95d10..e5b6aa45236a 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -74,6 +74,15 @@ typedef struct
Float4X4 projectionAndView;
} VertexShaderConstants;
+typedef struct
+{
+ float YCbCr_matrix[16];
+ float scRGB_output;
+ float SDR_whitelevel;
+ float HDR_whitelevel;
+ float maxCLL;
+} PixelShaderConstants;
+
/* Per-vertex data */
typedef struct
{
@@ -241,6 +250,10 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 color
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
return DXGI_FORMAT_NV12;
+ case SDL_PIXELFORMAT_P010:
+ return DXGI_FORMAT_P010;
+ case SDL_PIXELFORMAT_P016:
+ return DXGI_FORMAT_P016;
default:
return DXGI_FORMAT_UNKNOWN;
}
@@ -266,6 +279,9 @@ static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uin
case SDL_PIXELFORMAT_NV12: /* For the Y texture */
case SDL_PIXELFORMAT_NV21: /* For the Y texture */
return DXGI_FORMAT_R8_UNORM;
+ case SDL_PIXELFORMAT_P010: /* For the Y texture */
+ case SDL_PIXELFORMAT_P016: /* For the Y texture */
+ return DXGI_FORMAT_R16_UNORM;
default:
return DXGI_FORMAT_UNKNOWN;
}
@@ -1185,7 +1201,9 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
/* NV12 textures must have even width and height */
if (texture->format == SDL_PIXELFORMAT_NV12 ||
- texture->format == SDL_PIXELFORMAT_NV21) {
+ texture->format == SDL_PIXELFORMAT_NV21 ||
+ texture->format == SDL_PIXELFORMAT_P010 ||
+ texture->format == SDL_PIXELFORMAT_P016) {
textureDesc.Width = (textureDesc.Width + 1) & ~1;
textureDesc.Height = (textureDesc.Height + 1) & ~1;
}
@@ -1263,10 +1281,31 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
}
}
if (texture->format == SDL_PIXELFORMAT_NV12 ||
- texture->format == SDL_PIXELFORMAT_NV21) {
+ texture->format == SDL_PIXELFORMAT_NV21 ||
+ texture->format == SDL_PIXELFORMAT_P010 ||
+ texture->format == SDL_PIXELFORMAT_P016) {
textureData->nv12 = SDL_TRUE;
- textureData->shader = (texture->format == SDL_PIXELFORMAT_NV12 ? SHADER_NV12 : SHADER_NV21);
+ switch (texture->format) {
+ case SDL_PIXELFORMAT_NV12:
+ textureData->shader = SHADER_NV12;
+ break;
+ case SDL_PIXELFORMAT_NV21:
+ textureData->shader = SHADER_NV21;
+ break;
+ case SDL_PIXELFORMAT_P010:
+ case SDL_PIXELFORMAT_P016:
+ if(SDL_COLORSPACEPRIMARIES(texture->colorspace) == SDL_COLOR_PRIMARIES_BT2020 &&
+ SDL_COLORSPACETRANSFER(texture->colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
+ textureData->shader = SHADER_HDR10;
+ } else {
+ return SDL_SetError("Unsupported YUV colorspace");
+ }
+ break;
+ default:
+ /* This should never happen because of the check above */
+ return SDL_SetError("Unsupported YUV colorspace");
+ }
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
if (!textureData->shader_params) {
return SDL_SetError("Unsupported YUV colorspace");
@@ -1306,7 +1345,11 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
if (textureData->nv12) {
D3D11_SHADER_RESOURCE_VIEW_DESC nvResourceViewDesc = resourceViewDesc;
- nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM;
+ if (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21) {
+ nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM;
+ } else if (texture->format == SDL_PIXELFORMAT_P010 || texture->format == SDL_PIXELFORMAT_P016) {
+ nvResourceViewDesc.Format = DXGI_FORMAT_R16G16_UNORM;
+ }
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
(ID3D11Resource *)textureData->mainTexture,
@@ -1381,7 +1424,9 @@ static int D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Tex
stagingTextureDesc.MiscFlags = 0;
stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
- if (stagingTextureDesc.Format == DXGI_FORMAT_NV12) {
+ if (stagingTextureDesc.Format == DXGI_FORMAT_NV12 ||
+ stagingTextureDesc.Format == DXGI_FORMAT_P010 ||
+ stagingTextureDesc.Format == DXGI_FORMAT_P016) {
stagingTextureDesc.Width = (stagingTextureDesc.Width + 1) & ~1;
stagingTextureDesc.Height = (stagingTextureDesc.Height + 1) & ~1;
}
@@ -1424,7 +1469,9 @@ static int D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Tex
}
}
- if (stagingTextureDesc.Format == DXGI_FORMAT_NV12) {
+ if (stagingTextureDesc.Format == DXGI_FORMAT_NV12 ||
+ stagingTextureDesc.Format == DXGI_FORMAT_P010 ||
+ stagingTextureDesc.Format == DXGI_FORMAT_P016) {
/* Copy the UV plane as well */
h = (h + 1) / 2;
length = (length + 1) & ~1;
@@ -2132,19 +2179,36 @@ static int D3D11_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *c
if (shader_params != rendererData->currentShaderParams[shader]) {
if (shader_params) {
- const UINT shader_params_length = 4 * 4 * sizeof(float); /* The YUV shader takes 4 float4 parameters */
-
SAFE_RELEASE(rendererData->pixelShaderConstants[shader]);
+ PixelShaderConstants constants;
+ SDL_memcpy(constants.YCbCr_matrix, shader_params, sizeof(constants.YCbCr_matrix));
+ if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB) {
+ constants.scRGB_output = 1.0f;
+ } else {
+ constants.scRGB_output = 0.0f;
(Patch may be truncated, please check the link at the top of this post.)