Browse Source

Added support for HDR10 video playback on direct3d11

Fixes https://github.com/libsdl-org/SDL/issues/8053
Sam Lantinga 1 year ago
parent
commit
e74171b1ae

+ 23 - 1
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,
 

+ 515 - 0
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
+};

+ 92 - 0
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;
+}

+ 78 - 12
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;
+            }
+
+            /* Using some placeholder values here... */
+            const SDL_bool HDR = SDL_TRUE;
+            if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB && HDR) {
+                constants.SDR_whitelevel = 200.0f;
+                constants.HDR_whitelevel = 400.0f;
+            } else {
+                constants.SDR_whitelevel = 80.0f;
+                constants.HDR_whitelevel = 80.0f;
+            }
+            constants.maxCLL = 400.0f;
+
             D3D11_BUFFER_DESC desc;
             SDL_zero(desc);
             desc.Usage = D3D11_USAGE_DEFAULT;
-            desc.ByteWidth = shader_params_length;
+            desc.ByteWidth = sizeof(constants);
             desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
 
             D3D11_SUBRESOURCE_DATA data;
             SDL_zero(data);
-            data.pSysMem = shader_params;
+            data.pSysMem = &constants;
 
             HRESULT result = ID3D11Device_CreateBuffer(rendererData->d3dDevice, &desc, &data, &rendererData->pixelShaderConstants[shader]);
             if (FAILED(result)) {
@@ -2638,7 +2702,7 @@ SDL_RenderDriver D3D11_RenderDriver = {
         "direct3d11",
         (SDL_RENDERER_ACCELERATED |
          SDL_RENDERER_PRESENTVSYNC), /* flags.  see SDL_RendererFlags */
-        7,                           /* num_texture_formats */
+        9,                           /* num_texture_formats */
         {                            /* texture_formats */
           SDL_PIXELFORMAT_ARGB8888,
           SDL_PIXELFORMAT_XRGB8888,
@@ -2646,7 +2710,9 @@ SDL_RenderDriver D3D11_RenderDriver = {
           SDL_PIXELFORMAT_YV12,
           SDL_PIXELFORMAT_IYUV,
           SDL_PIXELFORMAT_NV12,
-          SDL_PIXELFORMAT_NV21 },
+          SDL_PIXELFORMAT_NV21,
+          SDL_PIXELFORMAT_P010,
+          SDL_PIXELFORMAT_P016 },
         0, /* max_texture_width: will be filled in later */
         0  /* max_texture_height: will be filled in later */
     }

+ 5 - 0
src/render/direct3d11/SDL_shaders_d3d11.c

@@ -56,6 +56,10 @@
 #include "D3D11_PixelShader_NV21.h"
 #undef g_main
 
+#define g_main D3D11_PixelShader_HDR10
+#include "D3D11_PixelShader_HDR10.h"
+#undef g_main
+
 #define g_main D3D11_VertexShader
 #include "D3D11_VertexShader.h"
 #undef g_main
@@ -73,6 +77,7 @@ static struct
     { D3D11_PixelShader_YUV, sizeof(D3D11_PixelShader_YUV) },
     { D3D11_PixelShader_NV12, sizeof(D3D11_PixelShader_NV12) },
     { D3D11_PixelShader_NV21, sizeof(D3D11_PixelShader_NV21) },
+    { D3D11_PixelShader_HDR10, sizeof(D3D11_PixelShader_HDR10) },
 #endif
 };
 SDL_COMPILE_TIME_ASSERT(D3D11_shaders, SDL_arraysize(D3D11_shaders) == NUM_SHADERS);

+ 1 - 0
src/render/direct3d11/SDL_shaders_d3d11.h

@@ -31,6 +31,7 @@ typedef enum
     SHADER_YUV,
     SHADER_NV12,
     SHADER_NV21,
+    SHADER_HDR10,
 #endif
     NUM_SHADERS
 } D3D11_Shader;

+ 1 - 0
src/render/direct3d11/compile_shaders.bat

@@ -3,4 +3,5 @@ fxc /T ps_4_0_level_9_1 /Fh D3D11_PixelShader_Textures.h D3D11_PixelShader_Textu
 fxc /T ps_4_0_level_9_1 /Fh D3D11_PixelShader_YUV.h D3D11_PixelShader_YUV.hlsl
 fxc /T ps_4_0_level_9_1 /Fh D3D11_PixelShader_NV12.h D3D11_PixelShader_NV12.hlsl
 fxc /T ps_4_0_level_9_1 /Fh D3D11_PixelShader_NV21.h D3D11_PixelShader_NV21.hlsl
+fxc /T ps_5_0 /Fh D3D11_PixelShader_HDR10.h D3D11_PixelShader_HDR10.hlsl
 fxc /T vs_4_0_level_9_1 /Fh D3D11_VertexShader.h D3D11_VertexShader.hlsl

+ 43 - 8
src/video/SDL_pixels.c

@@ -766,41 +766,60 @@ float SDL_PQfromNits(float v)
 
 const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace)
 {
-    static const float matBT601Limited[] = {
+    /* This is a helpful tool for deriving these:
+     * https://kdashg.github.io/misc/colors/from-coeffs.html
+     */
+    static const float mat_BT601_Limited_8bit[] = {
         -0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
         1.1644f,  0.0000f,  1.5960f, 0.0f,                  /* Rcoeff */
         1.1644f, -0.3918f, -0.8130f, 0.0f,                  /* Gcoeff */
         1.1644f,  2.0172f,  0.0000f, 0.0f,                  /* Bcoeff */
     };
 
-    static const float matBT601Full[] = {
+    static const float mat_BT601_Full_8bit[] = {
         0.0f, -0.501960814f, -0.501960814f, 0.0f,           /* offset */
         1.0000f,  0.0000f, 1.4020f, 0.0f,                   /* Rcoeff */
         1.0000f, -0.3441f, -0.7141f, 0.0f,                  /* Gcoeff */
         1.0000f,  1.7720f, 0.0000f, 0.0f,                   /* Bcoeff */
     };
 
-    static const float matBT709Limited[] = {
+    static const float mat_BT709_Limited_8bit[] = {
         -0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
         1.1644f,  0.0000f,  1.7927f, 0.0f,                  /* Rcoeff */
         1.1644f, -0.2132f, -0.5329f, 0.0f,                  /* Gcoeff */
         1.1644f,  2.1124f,  0.0000f, 0.0f,                  /* Bcoeff */
     };
 
-    static const float matBT709Full[] = {
+    static const float mat_BT709_Full_8bit[] = {
         0.0f, -0.501960814f, -0.501960814f, 0.0f,           /* offset */
         1.0000f,  0.0000f,  1.5748f, 0.0f,                  /* Rcoeff */
         1.0000f, -0.1873f, -0.4681f, 0.0f,                  /* Gcoeff */
         1.0000f,  1.8556f,  0.0000f, 0.0f,                  /* Bcoeff */
     };
 
+    static const float mat_BT2020_Limited_10bit[] = {
+        -0.062561095f, -0.500488759f, -0.500488759f, 0.0f,  /* offset */
+        1.1678f,  0.0000f,  1.6836f, 0.0f,                  /* Rcoeff */
+        1.1678f, -0.1879f, -0.6523f, 0.0f,                  /* Gcoeff */
+        1.1678f,  2.1481f,  0.0000f, 0.0f,                  /* Bcoeff */
+    };
+
+    static const float mat_BT2020_Full_10bit[] = {
+        0.0f, -0.500488759f, -0.500488759f, 0.0f,           /* offset */
+        1.0000f,  0.0000f,  1.4760f, 0.0f,                  /* Rcoeff */
+        1.0000f, -0.1647f, -0.5719f, 0.0f,                  /* Gcoeff */
+        1.0000f,  1.8832f,  0.0000f, 0.0f,                  /* Bcoeff */
+    };
+
     switch (SDL_COLORSPACEMATRIX(colorspace)) {
     case SDL_MATRIX_COEFFICIENTS_BT601:
         switch (SDL_COLORSPACERANGE(colorspace)) {
         case SDL_COLOR_RANGE_LIMITED:
-            return matBT601Limited;
+            return mat_BT601_Limited_8bit;
+            break;
         case SDL_COLOR_RANGE_FULL:
-            return matBT601Full;
+            return mat_BT601_Full_8bit;
+            break;
         default:
             break;
         }
@@ -808,9 +827,25 @@ const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace)
     case SDL_MATRIX_COEFFICIENTS_BT709:
         switch (SDL_COLORSPACERANGE(colorspace)) {
         case SDL_COLOR_RANGE_LIMITED:
-            return matBT709Limited;
+            return mat_BT709_Limited_8bit;
+            break;
+        case SDL_COLOR_RANGE_FULL:
+            return mat_BT709_Full_8bit;
+            break;
+        default:
+            break;
+        }
+        break;
+    /* FIXME: Are these the same? */
+    case SDL_MATRIX_COEFFICIENTS_BT2020_NCL:
+    case SDL_MATRIX_COEFFICIENTS_BT2020_CL:
+        switch (SDL_COLORSPACERANGE(colorspace)) {
+        case SDL_COLOR_RANGE_LIMITED:
+            return mat_BT2020_Limited_10bit;
+            break;
         case SDL_COLOR_RANGE_FULL:
-            return matBT709Full;
+            return mat_BT2020_Full_10bit;
+            break;
         default:
             break;
         }

+ 51 - 4
test/testffmpeg.c

@@ -24,6 +24,7 @@
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libavutil/avutil.h>
+#include <libavutil/mastering_display_metadata.h>
 #include <libavutil/pixdesc.h>
 #include <libswscale/swscale.h>
 
@@ -91,6 +92,7 @@ static int done;
 
 static SDL_bool CreateWindowAndRenderer(Uint32 window_flags, const char *driver)
 {
+    SDL_PropertiesID props;
     SDL_RendererInfo info;
     SDL_bool useEGL = (driver && SDL_strcmp(driver, "opengles2") == 0);
 
@@ -111,7 +113,23 @@ static SDL_bool CreateWindowAndRenderer(Uint32 window_flags, const char *driver)
     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
 
     /* The window will be resized to the video size when it's loaded, in OpenVideoStream() */
-    if (SDL_CreateWindowAndRenderer(320, 200, window_flags, &window, &renderer) < 0) {
+    window = SDL_CreateWindow("testffmpeg", 1920, 1080, 0);
+    if (!window) {
+        return SDL_FALSE;
+    }
+
+    props = SDL_CreateProperties();
+    SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, driver);
+    SDL_SetProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window);
+    SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SCRGB);
+    renderer = SDL_CreateRendererWithProperties(props);
+    if (!renderer) {
+        /* Try again with the sRGB colorspace */
+        SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB);
+        renderer = SDL_CreateRendererWithProperties(props);
+    }
+    SDL_DestroyProperties(props);
+    if (!renderer) {
         return SDL_FALSE;
     }
 
@@ -393,6 +411,7 @@ static AVCodecContext *OpenVideoStream(AVFormatContext *ic, int stream, const AV
     }
 
     SDL_SetWindowSize(window, codecpar->width, codecpar->height);
+    SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
 
     return context;
 }
@@ -401,7 +420,7 @@ static SDL_Colorspace GetFrameColorspace(AVFrame *frame)
 {
     SDL_Colorspace colorspace = SDL_COLORSPACE_SRGB;
 
-    if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
+    if (frame && frame->colorspace != AVCOL_SPC_RGB) {
         colorspace = SDL_DEFINE_COLORSPACE(SDL_COLOR_TYPE_YCBCR,
                                            frame->color_range,
                                            frame->color_primaries,
@@ -618,7 +637,7 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
     D3D11_TEXTURE2D_DESC desc;
     SDL_zero(desc);
     ID3D11Texture2D_GetDesc(pTexture, &desc);
-    if (desc.Format != DXGI_FORMAT_NV12) {
+    if (desc.Format != DXGI_FORMAT_NV12 && desc.Format != DXGI_FORMAT_P010 && desc.Format != DXGI_FORMAT_P016) {
         SDL_SetError("Unsupported texture format, expected DXGI_FORMAT_NV12, got %d", desc.Format);
         return SDL_FALSE;
     }
@@ -633,7 +652,21 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
 
         SDL_PropertiesID props = SDL_CreateProperties();
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
-        SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_NV12);
+        switch (desc.Format) {
+        case DXGI_FORMAT_NV12:
+            SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_NV12);
+            break;
+        case DXGI_FORMAT_P010:
+            SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_P010);
+            break;
+        case DXGI_FORMAT_P016:
+            SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_P016);
+            break;
+        default:
+            /* This should be checked above */
+            SDL_assert(!"Unknown pixel format");
+            break;
+        }
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, desc.Width);
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, desc.Height);
@@ -673,6 +706,20 @@ static SDL_bool GetTextureForFrame(AVFrame *frame, SDL_Texture **texture)
 
 static void DisplayVideoTexture(AVFrame *frame)
 {
+#if 1 /* This data doesn't seem to be valid in any of the videos I've tried */
+    AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+    if (sd) {
+        AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data;
+        mdm = mdm;
+    }
+
+    sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+    if (sd) {
+        AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
+        clm = clm;
+    }
+#endif /* 0 */
+
     /* Update the video texture */
     if (!GetTextureForFrame(frame, &video_texture)) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't get texture for frame: %s\n", SDL_GetError());