[vlc-devel] [PATCH 5/5] direct3d11: pass the Whitepoint shifts as a Matrix

Steve Lhomme robux4 at videolabs.io
Mon Mar 6 17:57:53 CET 2017


This way we get the RGB from the sampled pixel using 2 matrix multiplications.
It may be more efficient than adding values separately
---
 modules/video_output/win32/direct3d11.c | 47 ++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index fedfb090b9..53f8f625ec 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -172,8 +172,7 @@ typedef struct {
 } PS_CONSTANT_BUFFER;
 
 typedef struct {
-    FLOAT WhitePoint[3];
-    FLOAT whitePadding;
+    FLOAT WhitePoint[4*4];
     FLOAT Colorspace[4*4];
 } PS_COLOR_TRANSFORM;
 
@@ -286,10 +285,7 @@ static const char* globPixelShaderDefault = "\
   };\
   cbuffer PS_COLOR_TRANSFORM : register(b1)\
   {\
-    float WhitePointX;\
-    float WhitePointY;\
-    float WhitePointZ;\
-    float whitePadding;\
+    float4x4 WhitePoint;\
     float4x4 Colorspace;\
   };\
   Texture2D%s shaderTexture[" STRINGIZE(D3D11_MAX_SHADER_VIEW) "];\
@@ -343,12 +339,7 @@ static const char* globPixelShaderDefault = "\
     float4 sample;\
     \
     %s /* sampling routine in sample */\
-    float4 rgba;\
-    rgba.x = sample.x + WhitePointX;\
-    rgba.y = sample.y + WhitePointY;\
-    rgba.z = sample.z + WhitePointZ;\
-    rgba.a = sample.a * Opacity;\
-    rgba = mul(rgba, Colorspace);\
+    float4 rgba = mul(mul(sample, WhitePoint), Colorspace);\
     float opacity = rgba.a * Opacity;\
     float3 rgb = (float3)rgba;\
     rgb = sourceToLinear(rgb);\
@@ -2189,11 +2180,6 @@ static int SetupQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
         goto error;
     }
 
-#define FULL_TO_STUDIO_SHIFT (16.f / 256.f)
-    FLOAT WHITE_POINT_D65_TO_FULL[4] = { -FULL_TO_STUDIO_SHIFT, -0.5f, -0.5f, 1.f };
-    if (RGB_shader)
-        WHITE_POINT_D65_TO_FULL[0] = WHITE_POINT_D65_TO_FULL[1] = WHITE_POINT_D65_TO_FULL[2] = 0.f;
-
     static const FLOAT COLORSPACE_RGB_FULL[4 * 4] = {
         1.f, 0.f, 0.f, 0.f,
         0.f, 1.f, 0.f, 0.f,
@@ -2249,23 +2235,42 @@ static int SetupQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
     }
 
     memcpy(colorspace.Colorspace, ppColorspace, sizeof(colorspace.Colorspace));
-    memcpy(colorspace.WhitePoint, WHITE_POINT_D65_TO_FULL, sizeof(colorspace.WhitePoint));
+    memcpy(colorspace.WhitePoint, COLORSPACE_RGB_FULL, sizeof(colorspace.WhitePoint));
+
+    if (!RGB_shader)
+    {
+#define CbCr_ACHROMACY 0.5f /* 128 on 8 bits and 512 on 10 bits, etc */
+        colorspace.WhitePoint[1*4 + 3] = -CbCr_ACHROMACY;
+        colorspace.WhitePoint[2*4 + 3] = -CbCr_ACHROMACY;
+    }
 
+    /* get to the full range */
+#define FULL_TO_STUDIO_SHIFT (16.f / 256.f)
+    FLOAT range_shift = fmt->b_color_range_full ? 0.f : -FULL_TO_STUDIO_SHIFT;
     if (sys->display_is_limited_range) {
+        /* the display assumes the source is in limited range */
         static const FLOAT FULL_TO_STUDIO_RATIO = (256.f - 16.f - 20.f) / 256.f;
         /* limit to 16-235 range as it's expanded again by the hardware */
-        WHITE_POINT_D65_TO_FULL[0] += FULL_TO_STUDIO_SHIFT;
         if (RGB_shader) {
-            WHITE_POINT_D65_TO_FULL[1] += FULL_TO_STUDIO_SHIFT;
-            WHITE_POINT_D65_TO_FULL[2] += FULL_TO_STUDIO_SHIFT;
+            /* expand each color's range */
             colorspace.Colorspace[0 * 5] *= FULL_TO_STUDIO_RATIO;
             colorspace.Colorspace[1 * 5] *= FULL_TO_STUDIO_RATIO;
             colorspace.Colorspace[2 * 5] *= FULL_TO_STUDIO_RATIO;
         } else {
+            /* expand the luminance range */
             colorspace.Colorspace[0 * 4] *= FULL_TO_STUDIO_RATIO;
             colorspace.Colorspace[1 * 4] *= FULL_TO_STUDIO_RATIO;
             colorspace.Colorspace[2 * 4] *= FULL_TO_STUDIO_RATIO;
         }
+
+        range_shift += FULL_TO_STUDIO_SHIFT;
+    }
+
+    colorspace.Colorspace[0*4 + 3] = range_shift;
+    if (RGB_shader)
+    {
+        colorspace.Colorspace[1*4 + 3] = range_shift;
+        colorspace.Colorspace[2*4 + 3] = range_shift;
     }
 
     constantInit.pSysMem = &colorspace;
-- 
2.11.1



More information about the vlc-devel mailing list