[vlc-commits] d3d11: move D3D11_CompilePixelShader in d3d11_shaders.c

Steve Lhomme git at videolan.org
Mon May 28 13:25:15 CEST 2018


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Feb 20 17:41:01 2018 +0100| [fe1b7df30daf73d5ec740c10d94fc2eb09c542f7] | committer: Steve Lhomme

d3d11: move D3D11_CompilePixelShader in d3d11_shaders.c

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fe1b7df30daf73d5ec740c10d94fc2eb09c542f7
---

 modules/video_output/win32/d3d11_shaders.c | 350 +++++++++++++++++++++++++++
 modules/video_output/win32/d3d11_shaders.h |  29 +++
 modules/video_output/win32/direct3d11.c    | 373 +----------------------------
 3 files changed, 381 insertions(+), 371 deletions(-)

diff --git a/modules/video_output/win32/d3d11_shaders.c b/modules/video_output/win32/d3d11_shaders.c
index 219b94e706..101149e0d8 100644
--- a/modules/video_output/win32/d3d11_shaders.c
+++ b/modules/video_output/win32/d3d11_shaders.c
@@ -42,6 +42,356 @@
 # define D3DCompile(args...)                    hd3d->OurD3DCompile(args)
 #endif
 
+#define ST2084_PQ_CONSTANTS  "const float ST2084_m1 = 2610.0 / (4096.0 * 4);\n\
+const float ST2084_m2 = (2523.0 / 4096.0) * 128.0;\n\
+const float ST2084_c1 = 3424.0 / 4096.0;\n\
+const float ST2084_c2 = (2413.0 / 4096.0) * 32.0;\n\
+const float ST2084_c3 = (2392.0 / 4096.0) * 32.0;\n"
+
+#define STRINGIZE2(s) #s
+#define STRINGIZE(s) STRINGIZE2(s)
+
+static const char* globPixelShaderDefault = "\
+  cbuffer PS_CONSTANT_BUFFER : register(b0)\n\
+  {\n\
+    float Opacity;\n\
+    float BoundaryX;\n\
+    float BoundaryY;\n\
+    float LuminanceScale;\n\
+  };\n\
+  cbuffer PS_COLOR_TRANSFORM : register(b1)\n\
+  {\n\
+    float4x4 WhitePoint;\n\
+    float4x4 Colorspace;\n\
+  };\n\
+  Texture2D%s shaderTexture[" STRINGIZE(D3D11_MAX_SHADER_VIEW) "];\n\
+  SamplerState SamplerStates[2];\n\
+  \n\
+  struct PS_INPUT\n\
+  {\n\
+    float4 Position   : SV_POSITION;\n\
+    float4 Texture    : TEXCOORD0;\n\
+  };\n\
+  \n\
+  /* see http://filmicworlds.com/blog/filmic-tonemapping-operators/ */\n\
+  inline float3 hable(float3 x) {\n\
+      const float A = 0.15, B = 0.50, C = 0.10, D = 0.20, E = 0.02, F = 0.30;\n\
+      return ((x * (A*x + (C*B))+(D*E))/(x * (A*x + B) + (D*F))) - E/F;\n\
+  }\n\
+  \n\
+  /* https://en.wikipedia.org/wiki/Hybrid_Log-Gamma#Technical_details */\n\
+  inline float inverse_HLG(float x){\n\
+      const float B67_a = 0.17883277;\n\
+      const float B67_b = 0.28466892;\n\
+      const float B67_c = 0.55991073;\n\
+      const float B67_inv_r2 = 4.0; /* 1/0.5² */\n\
+      if (x <= 0.5)\n\
+          x = x * x * B67_inv_r2;\n\
+      else\n\
+          x = exp((x - B67_c) / B67_a) + B67_b;\n\
+      return x;\n\
+  }\n\
+  \n\
+  inline float3 sourceToLinear(float3 rgb) {\n\
+      %s;\n\
+  }\n\
+  \n\
+  inline float3 linearToDisplay(float3 rgb) {\n\
+      %s;\n\
+  }\n\
+  \n\
+  inline float3 toneMapping(float3 rgb) {\n\
+      %s;\n\
+  }\n\
+  \n\
+  inline float3 adjustRange(float3 rgb) {\n\
+      %s;\n\
+  }\n\
+  \n\
+  inline float4 sampleTexture(SamplerState samplerState, float4 coords) {\n\
+      float4 sample;\n\
+      %s /* sampling routine in sample */\n\
+      return sample;\n\
+  }\n\
+  \n\
+  float4 main( PS_INPUT In ) : SV_TARGET\n\
+  {\n\
+    float4 sample;\n\
+    \n\
+    if (In.Texture.x > BoundaryX || In.Texture.y > BoundaryY) \n\
+        sample = sampleTexture( SamplerStates[1], In.Texture );\n\
+    else\n\
+        sample = sampleTexture( SamplerStates[0], In.Texture );\n\
+    float4 rgba = mul(mul(sample, WhitePoint), Colorspace);\n\
+    float opacity = rgba.a * Opacity;\n\
+    float3 rgb = (float3)rgba;\n\
+    rgb = sourceToLinear(rgb);\n\
+    rgb = toneMapping(rgb);\n\
+    rgb = linearToDisplay(rgb);\n\
+    rgb = adjustRange(rgb);\n\
+    return float4(rgb, saturate(opacity));\n\
+  }\n\
+";
+
+bool IsRGBShader(const d3d_format_t *cfg)
+{
+    return cfg->resourceFormat[0] != DXGI_FORMAT_R8_UNORM &&
+           cfg->resourceFormat[0] != DXGI_FORMAT_R16_UNORM &&
+           cfg->formatTexture != DXGI_FORMAT_YUY2;
+}
+
+#undef D3D11_CompilePixelShader
+HRESULT D3D11_CompilePixelShader(vlc_object_t *o, d3d11_handle_t *hd3d, bool legacy_shader,
+                                 d3d11_device_t *d3d_dev,
+                                 const d3d_format_t *format, const display_info_t *display,
+                                 video_transfer_func_t transfer, bool src_full_range,
+                                 ID3D11PixelShader **output)
+{
+    static const char *DEFAULT_NOOP = "return rgb";
+    const char *psz_sampler;
+    const char *psz_src_transform     = DEFAULT_NOOP;
+    const char *psz_display_transform = DEFAULT_NOOP;
+    const char *psz_tone_mapping      = DEFAULT_NOOP;
+    const char *psz_adjust_range      = DEFAULT_NOOP;
+    char *psz_range = NULL;
+
+    switch (format->formatTexture)
+    {
+    case DXGI_FORMAT_NV12:
+    case DXGI_FORMAT_P010:
+        psz_sampler =
+                "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
+                sample.yz = shaderTexture[1].Sample(samplerState, coords).xy;\
+                sample.a  = 1;";
+        break;
+    case DXGI_FORMAT_YUY2:
+        psz_sampler =
+                "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
+                sample.y  = shaderTexture[0].Sample(samplerState, coords).y;\
+                sample.z  = shaderTexture[0].Sample(samplerState, coords).a;\
+                sample.a  = 1;";
+        break;
+    case DXGI_FORMAT_R8G8B8A8_UNORM:
+    case DXGI_FORMAT_B8G8R8A8_UNORM:
+    case DXGI_FORMAT_B8G8R8X8_UNORM:
+    case DXGI_FORMAT_B5G6R5_UNORM:
+        psz_sampler =
+                "sample = shaderTexture[0].Sample(samplerState, coords);";
+        break;
+    case DXGI_FORMAT_UNKNOWN:
+        if (format->fourcc == VLC_CODEC_I420_10L)
+            psz_sampler =
+                   "sample.x  = shaderTexture[0].Sample(samplerState, coords).x * 64;\
+                    sample.y  = shaderTexture[1].Sample(samplerState, coords).x * 64;\
+                    sample.z  = shaderTexture[2].Sample(samplerState, coords).x * 64;\
+                    sample.a  = 1;";
+        else
+            psz_sampler =
+                   "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
+                    sample.y  = shaderTexture[1].Sample(samplerState, coords).x;\
+                    sample.z  = shaderTexture[2].Sample(samplerState, coords).x;\
+                    sample.a  = 1;";
+        break;
+    default:
+        vlc_assert_unreachable();
+    }
+
+    video_transfer_func_t src_transfer;
+
+    if (transfer != display->colorspace->transfer)
+    {
+        /* we need to go in linear mode */
+        switch (transfer)
+        {
+            case TRANSFER_FUNC_SMPTE_ST2084:
+                /* ST2084 to Linear */
+                psz_src_transform =
+                       ST2084_PQ_CONSTANTS
+                       "rgb = pow(rgb, 1.0/ST2084_m2);\
+                        rgb = max(rgb - ST2084_c1, 0.0) / (ST2084_c2 - ST2084_c3 * rgb);\
+                        rgb = pow(rgb, 1.0/ST2084_m1);\
+                        return rgb";
+                src_transfer = TRANSFER_FUNC_LINEAR;
+                break;
+            case TRANSFER_FUNC_HLG:
+                /* HLG to Linear */
+                psz_src_transform =
+                       "rgb.r = inverse_HLG(rgb.r);\
+                        rgb.g = inverse_HLG(rgb.g);\
+                        rgb.b = inverse_HLG(rgb.b);\
+                        return rgb / 20.0";
+                src_transfer = TRANSFER_FUNC_LINEAR;
+                break;
+            case TRANSFER_FUNC_BT709:
+                psz_src_transform = "return pow(rgb, 1.0 / 0.45)";
+                src_transfer = TRANSFER_FUNC_LINEAR;
+                break;
+            case TRANSFER_FUNC_BT470_M:
+            case TRANSFER_FUNC_SRGB:
+                psz_src_transform = "return pow(rgb, 2.2)";
+                src_transfer = TRANSFER_FUNC_LINEAR;
+                break;
+            case TRANSFER_FUNC_BT470_BG:
+                psz_src_transform = "return pow(rgb, 2.8)";
+                src_transfer = TRANSFER_FUNC_LINEAR;
+                break;
+            default:
+                msg_Dbg(o, "unhandled source transfer %d", transfer);
+                src_transfer = transfer;
+                break;
+        }
+
+        switch (display->colorspace->transfer)
+        {
+            case TRANSFER_FUNC_SRGB:
+                if (src_transfer == TRANSFER_FUNC_LINEAR)
+                {
+                    /* Linear to sRGB */
+                    psz_display_transform = "return pow(rgb, 1.0 / 2.2)";
+
+                    if (transfer == TRANSFER_FUNC_SMPTE_ST2084 || transfer == TRANSFER_FUNC_HLG)
+                    {
+                        /* HDR tone mapping */
+                        psz_tone_mapping =
+                            "static const float3 HABLE_DIV = hable(11.2);\
+                            rgb = hable(rgb * LuminanceScale) / HABLE_DIV;\
+                            return rgb";
+                    }
+                }
+                else
+                    msg_Warn(o, "don't know how to transfer from %d to sRGB", src_transfer);
+                break;
+
+            case TRANSFER_FUNC_SMPTE_ST2084:
+                if (src_transfer == TRANSFER_FUNC_LINEAR)
+                {
+                    /* Linear to ST2084 */
+                    psz_display_transform =
+                           ST2084_PQ_CONSTANTS
+                           "rgb = pow(rgb, ST2084_m1);\
+                            rgb = (ST2084_c1 + ST2084_c2 * rgb) / (1 + ST2084_c3 * rgb);\
+                            rgb = pow(rgb, ST2084_m2);\
+                            return rgb";
+                }
+                else
+                    msg_Warn(o, "don't know how to transfer from %d to SMPTE ST 2084", src_transfer);
+                break;
+            default:
+                msg_Warn(o, "don't know how to transfer from %d to %d", src_transfer, display->colorspace->transfer);
+                break;
+        }
+    }
+
+    int range_adjust = 0;
+    if (display->colorspace->b_full_range) {
+        if (!src_full_range)
+            range_adjust = 1; /* raise the source to full range */
+    } else {
+        if (src_full_range)
+            range_adjust = -1; /* lower the source to studio range */
+    }
+    if (!IsRGBShader(format) && !src_full_range)
+        range_adjust--; /* the YUV->RGB conversion already output full range */
+
+    if (range_adjust != 0)
+    {
+        psz_range = malloc(256);
+        if (likely(psz_range))
+        {
+            FLOAT itu_black_level;
+            FLOAT itu_range_factor;
+            FLOAT itu_white_level;
+            switch (format->bitsPerChannel)
+            {
+            case 8:
+                /* Rec. ITU-R BT.709-6 §4.6 */
+                itu_black_level  =              16.f / 255.f;
+                itu_white_level  =             235.f / 255.f;
+                itu_range_factor = (float)(235 - 16) / 255.f;
+                break;
+            case 10:
+                /* Rec. ITU-R BT.709-6 §4.6 */
+                itu_black_level  =              64.f / 1023.f;
+                itu_white_level  =             940.f / 1023.f;
+                itu_range_factor = (float)(940 - 64) / 1023.f;
+                break;
+            case 12:
+                /* Rec. ITU-R BT.2020-2 Table 5 */
+                itu_black_level  =               256.f / 4095.f;
+                itu_white_level  =              3760.f / 4095.f;
+                itu_range_factor = (float)(3760 - 256) / 4095.f;
+                break;
+            default:
+                /* unknown bitdepth, use approximation for infinite bit depth */
+                itu_black_level  =              16.f / 256.f;
+                itu_white_level  =             235.f / 256.f;
+                itu_range_factor = (float)(235 - 16) / 256.f;
+                break;
+            }
+
+            FLOAT black_level = 0;
+            FLOAT range_factor = 1.0f;
+            if (range_adjust > 0)
+            {
+                /* expand the range from studio to full range */
+                while (range_adjust--)
+                {
+                    black_level -= itu_black_level;
+                    range_factor /= itu_range_factor;
+                }
+                sprintf(psz_range, "return max(0,min(1,(rgb + %f) * %f))",
+                        black_level, range_factor);
+            }
+            else
+            {
+                /* shrink the range to studio range */
+                while (range_adjust++)
+                {
+                    black_level += itu_black_level;
+                    range_factor *= itu_range_factor;
+                }
+                sprintf(psz_range, "return clamp(rgb + %f * %f,%f,%f)",
+                        black_level, range_factor, itu_black_level, itu_white_level);
+            }
+            psz_adjust_range = psz_range;
+        }
+    }
+
+    char *shader = malloc(strlen(globPixelShaderDefault) + 32 + strlen(psz_sampler) +
+                          strlen(psz_src_transform) + strlen(psz_display_transform) +
+                          strlen(psz_tone_mapping) + strlen(psz_adjust_range));
+    if (!shader)
+    {
+        msg_Err(o, "no room for the Pixel Shader");
+        free(psz_range);
+        return E_OUTOFMEMORY;
+    }
+    sprintf(shader, globPixelShaderDefault, legacy_shader ? "" : "Array", psz_src_transform,
+            psz_display_transform, psz_tone_mapping, psz_adjust_range, psz_sampler);
+#ifndef NDEBUG
+    if (!IsRGBShader(format)) {
+        msg_Dbg(o,"psz_src_transform %s", psz_src_transform);
+        msg_Dbg(o,"psz_tone_mapping %s", psz_tone_mapping);
+        msg_Dbg(o,"psz_display_transform %s", psz_display_transform);
+        msg_Dbg(o,"psz_adjust_range %s", psz_adjust_range);
+        msg_Dbg(o,"psz_sampler %s", psz_sampler);
+    }
+#endif
+    free(psz_range);
+
+    ID3DBlob *pPSBlob = D3D11_CompileShader(o, hd3d, d3d_dev, shader, true);
+    free(shader);
+    if (!pPSBlob)
+        return E_INVALIDARG;
+
+    HRESULT hr = ID3D11Device_CreatePixelShader(d3d_dev->d3ddevice,
+                                                (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
+                                                ID3D10Blob_GetBufferSize(pPSBlob), NULL, output);
+
+    ID3D10Blob_Release(pPSBlob);
+    return hr;
+}
+
 #undef D3D11_CompileShader
 ID3DBlob* D3D11_CompileShader(vlc_object_t *obj, const d3d11_handle_t *hd3d, const d3d11_device_t *d3d_dev,
                               const char *psz_shader, bool pixel)
diff --git a/modules/video_output/win32/d3d11_shaders.h b/modules/video_output/win32/d3d11_shaders.h
index 6bb23f9dfc..d965d9472e 100644
--- a/modules/video_output/win32/d3d11_shaders.h
+++ b/modules/video_output/win32/d3d11_shaders.h
@@ -24,9 +24,38 @@
 #define VLC_D3D11_SHADERS_H
 
 #include "../../video_chroma/d3d11_fmt.h"
+#include <dxgi1_4.h>
+
+typedef enum video_color_axis {
+    COLOR_AXIS_RGB,
+    COLOR_AXIS_YCBCR,
+} video_color_axis;
+
+typedef struct {
+    DXGI_COLOR_SPACE_TYPE   dxgi;
+    const char              *name;
+    video_color_axis        axis;
+    video_color_primaries_t primaries;
+    video_transfer_func_t   transfer;
+    video_color_space_t     color;
+    bool                    b_full_range;
+} dxgi_color_space;
+
+typedef struct {
+    const dxgi_color_space   *colorspace;
+    unsigned                 luminance_peak;
+} display_info_t;
 
 ID3DBlob* D3D11_CompileShader(vlc_object_t *, const d3d11_handle_t *, const d3d11_device_t *,
                               const char *psz_shader, bool pixel);
 #define D3D11_CompileShader(a,b,c,d,e)  D3D11_CompileShader(VLC_OBJECT(a),b,c,d,e)
 
+bool IsRGBShader(const d3d_format_t *);
+
+HRESULT D3D11_CompilePixelShader(vlc_object_t *, d3d11_handle_t *, bool legacy_shader,
+                                 d3d11_device_t *, const d3d_format_t *, const display_info_t *,
+                                 video_transfer_func_t, bool src_full_range,
+                                 ID3D11PixelShader **output);
+#define D3D11_CompilePixelShader(a,b,c,d,e,f,g,h,i) \
+    D3D11_CompilePixelShader(VLC_OBJECT(a),b,c,d,e,f,g,h,i)
 #endif /* VLC_D3D11_SHADERS_H */
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index eb8b427031..87e66f943d 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -89,26 +89,6 @@ vlc_module_begin ()
     set_callbacks(Open, Close)
 vlc_module_end ()
 
-typedef enum video_color_axis {
-    COLOR_AXIS_RGB,
-    COLOR_AXIS_YCBCR,
-} video_color_axis;
-
-typedef struct {
-    DXGI_COLOR_SPACE_TYPE   dxgi;
-    const char              *name;
-    video_color_axis        axis;
-    video_color_primaries_t primaries;
-    video_transfer_func_t   transfer;
-    video_color_space_t     color;
-    bool                    b_full_range;
-} dxgi_color_space;
-
-typedef struct {
-    const dxgi_color_space   *colorspace;
-    unsigned                 luminance_peak;
-} display_info_t;
-
 struct vout_display_sys_t
 {
     vout_display_sys_win32_t sys;
@@ -229,9 +209,6 @@ static const char* globVertexShaderFlat = "\
   }\
 ";
 
-#define STRINGIZE2(s) #s
-#define STRINGIZE(s) STRINGIZE2(s)
-
 static const char* globVertexShaderProjection = "\
   cbuffer VS_PROJECTION_CONST : register(b0)\
   {\
@@ -268,94 +245,6 @@ static const char* globVertexShaderProjection = "\
   }\
 ";
 
-static const char* globPixelShaderDefault = "\
-  cbuffer PS_CONSTANT_BUFFER : register(b0)\
-  {\
-    float Opacity;\
-    float BoundaryX;\
-    float BoundaryY;\
-    float LuminanceScale;\
-  };\
-  cbuffer PS_COLOR_TRANSFORM : register(b1)\
-  {\
-    float4x4 WhitePoint;\
-    float4x4 Colorspace;\
-  };\
-  Texture2D%s shaderTexture[" STRINGIZE(D3D11_MAX_SHADER_VIEW) "];\
-  SamplerState SamplerStates[2];\
-  \
-  struct PS_INPUT\
-  {\
-    float4 Position   : SV_POSITION;\
-    float4 Texture    : TEXCOORD0;\
-  };\
-  \
-  /* see http://filmicworlds.com/blog/filmic-tonemapping-operators/ */\
-  inline float3 hable(float3 x) {\
-      const float A = 0.15, B = 0.50, C = 0.10, D = 0.20, E = 0.02, F = 0.30;\
-      return ((x * (A*x + (C*B))+(D*E))/(x * (A*x + B) + (D*F))) - E/F;\
-  }\
-  \
-  /* https://en.wikipedia.org/wiki/Hybrid_Log-Gamma#Technical_details */\
-  inline float inverse_HLG(float x){\
-      const float B67_a = 0.17883277;\
-      const float B67_b = 0.28466892;\
-      const float B67_c = 0.55991073;\
-      const float B67_inv_r2 = 4.0; /* 1/0.5² */\
-      if (x <= 0.5)\
-          x = x * x * B67_inv_r2;\
-      else\
-          x = exp((x - B67_c) / B67_a) + B67_b;\
-      return x;\
-  }\
-  \
-  inline float3 sourceToLinear(float3 rgb) {\
-      %s;\
-  }\
-  \
-  inline float3 linearToDisplay(float3 rgb) {\
-      %s;\
-  }\
-  \
-  inline float3 toneMapping(float3 rgb) {\
-      %s;\
-  }\
-  \
-  inline float3 adjustRange(float3 rgb) {\
-      %s;\
-  }\
-  \
-  inline float4 sampleTexture(SamplerState samplerState, float4 coords) {\
-      float4 sample;\
-      %s /* sampling routine in sample */\
-      return sample;\
-  }\
-  \
-  float4 main( PS_INPUT In ) : SV_TARGET\
-  {\
-    float4 sample;\
-    \
-    if (In.Texture.x > BoundaryX || In.Texture.y > BoundaryY) \
-        sample = sampleTexture( SamplerStates[1], In.Texture );\
-    else\
-        sample = sampleTexture( SamplerStates[0], In.Texture );\
-    float4 rgba = mul(mul(sample, WhitePoint), Colorspace);\
-    float opacity = rgba.a * Opacity;\
-    float3 rgb = (float3)rgba;\
-    rgb = sourceToLinear(rgb);\
-    rgb = toneMapping(rgb);\
-    rgb = linearToDisplay(rgb);\
-    rgb = adjustRange(rgb);\
-    return float4(rgb, saturate(opacity));\
-  }\
-";
-
-#define ST2084_PQ_CONSTANTS  "const float ST2084_m1 = 2610.0 / (4096.0 * 4);\
-const float ST2084_m2 = (2523.0 / 4096.0) * 128.0;\
-const float ST2084_c1 = 3424.0 / 4096.0;\
-const float ST2084_c2 = (2413.0 / 4096.0) * 32.0;\
-const float ST2084_c3 = (2392.0 / 4096.0) * 32.0;"
-
 static int Direct3D11MapPoolTexture(picture_t *picture)
 {
     picture_sys_t *p_sys = picture->p_sys;
@@ -1646,264 +1535,6 @@ static void UpdatePicQuadPosition(vout_display_t *vd)
 #endif
 }
 
-static bool IsRGBShader(const d3d_format_t *cfg)
-{
-    return cfg->resourceFormat[0] != DXGI_FORMAT_R8_UNORM &&
-           cfg->resourceFormat[0] != DXGI_FORMAT_R16_UNORM &&
-           cfg->formatTexture != DXGI_FORMAT_YUY2;
-}
-
-static HRESULT D3D11_CompilePixelShader(vlc_object_t *vd, d3d11_handle_t *hd3d, bool legacy_shader,
-                                        d3d11_device_t *d3d_dev,
-                                        const d3d_format_t *format, const display_info_t *display,
-                                        video_transfer_func_t transfer, bool src_full_range,
-                                        ID3D11PixelShader **output)
-{
-    static const char *DEFAULT_NOOP = "return rgb";
-    const char *psz_sampler;
-    const char *psz_src_transform     = DEFAULT_NOOP;
-    const char *psz_display_transform = DEFAULT_NOOP;
-    const char *psz_tone_mapping      = DEFAULT_NOOP;
-    const char *psz_adjust_range      = DEFAULT_NOOP;
-    char *psz_range = NULL;
-
-    switch (format->formatTexture)
-    {
-    case DXGI_FORMAT_NV12:
-    case DXGI_FORMAT_P010:
-        psz_sampler =
-                "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
-                sample.yz = shaderTexture[1].Sample(samplerState, coords).xy;\
-                sample.a  = 1;";
-        break;
-    case DXGI_FORMAT_YUY2:
-        psz_sampler =
-                "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
-                sample.y  = shaderTexture[0].Sample(samplerState, coords).y;\
-                sample.z  = shaderTexture[0].Sample(samplerState, coords).a;\
-                sample.a  = 1;";
-        break;
-    case DXGI_FORMAT_R8G8B8A8_UNORM:
-    case DXGI_FORMAT_B8G8R8A8_UNORM:
-    case DXGI_FORMAT_B8G8R8X8_UNORM:
-    case DXGI_FORMAT_B5G6R5_UNORM:
-        psz_sampler =
-                "sample = shaderTexture[0].Sample(samplerState, coords);";
-        break;
-    case DXGI_FORMAT_UNKNOWN:
-        if (format->fourcc == VLC_CODEC_I420_10L)
-            psz_sampler =
-                   "sample.x  = shaderTexture[0].Sample(samplerState, coords).x * 64;\
-                    sample.y  = shaderTexture[1].Sample(samplerState, coords).x * 64;\
-                    sample.z  = shaderTexture[2].Sample(samplerState, coords).x * 64;\
-                    sample.a  = 1;";
-        else
-            psz_sampler =
-                   "sample.x  = shaderTexture[0].Sample(samplerState, coords).x;\
-                    sample.y  = shaderTexture[1].Sample(samplerState, coords).x;\
-                    sample.z  = shaderTexture[2].Sample(samplerState, coords).x;\
-                    sample.a  = 1;";
-        break;
-    default:
-        vlc_assert_unreachable();
-    }
-
-    video_transfer_func_t src_transfer;
-
-    if (transfer != display->colorspace->transfer)
-    {
-        /* we need to go in linear mode */
-        switch (transfer)
-        {
-            case TRANSFER_FUNC_SMPTE_ST2084:
-                /* ST2084 to Linear */
-                psz_src_transform =
-                       ST2084_PQ_CONSTANTS
-                       "rgb = pow(rgb, 1.0/ST2084_m2);\
-                        rgb = max(rgb - ST2084_c1, 0.0) / (ST2084_c2 - ST2084_c3 * rgb);\
-                        rgb = pow(rgb, 1.0/ST2084_m1);\
-                        return rgb";
-                src_transfer = TRANSFER_FUNC_LINEAR;
-                break;
-            case TRANSFER_FUNC_HLG:
-                /* HLG to Linear */
-                psz_src_transform =
-                       "rgb.r = inverse_HLG(rgb.r);\
-                        rgb.g = inverse_HLG(rgb.g);\
-                        rgb.b = inverse_HLG(rgb.b);\
-                        return rgb / 20.0";
-                src_transfer = TRANSFER_FUNC_LINEAR;
-                break;
-            case TRANSFER_FUNC_BT709:
-                psz_src_transform = "return pow(rgb, 1.0 / 0.45)";
-                src_transfer = TRANSFER_FUNC_LINEAR;
-                break;
-            case TRANSFER_FUNC_BT470_M:
-            case TRANSFER_FUNC_SRGB:
-                psz_src_transform = "return pow(rgb, 2.2)";
-                src_transfer = TRANSFER_FUNC_LINEAR;
-                break;
-            case TRANSFER_FUNC_BT470_BG:
-                psz_src_transform = "return pow(rgb, 2.8)";
-                src_transfer = TRANSFER_FUNC_LINEAR;
-                break;
-            default:
-                msg_Dbg(vd, "unhandled source transfer %d", transfer);
-                src_transfer = transfer;
-                break;
-        }
-
-        switch (display->colorspace->transfer)
-        {
-            case TRANSFER_FUNC_SRGB:
-                if (src_transfer == TRANSFER_FUNC_LINEAR)
-                {
-                    /* Linear to sRGB */
-                    psz_display_transform = "return pow(rgb, 1.0 / 2.2)";
-
-                    if (transfer == TRANSFER_FUNC_SMPTE_ST2084 || transfer == TRANSFER_FUNC_HLG)
-                    {
-                        /* HDR tone mapping */
-                        psz_tone_mapping =
-                            "static const float3 HABLE_DIV = hable(11.2);\
-                            rgb = hable(rgb * LuminanceScale) / HABLE_DIV;\
-                            return rgb";
-                    }
-                }
-                else
-                    msg_Warn(vd, "don't know how to transfer from %d to sRGB", src_transfer);
-                break;
-
-            case TRANSFER_FUNC_SMPTE_ST2084:
-                if (src_transfer == TRANSFER_FUNC_LINEAR)
-                {
-                    /* Linear to ST2084 */
-                    psz_display_transform =
-                           ST2084_PQ_CONSTANTS
-                           "rgb = pow(rgb, ST2084_m1);\
-                            rgb = (ST2084_c1 + ST2084_c2 * rgb) / (1 + ST2084_c3 * rgb);\
-                            rgb = pow(rgb, ST2084_m2);\
-                            return rgb";
-                }
-                else
-                    msg_Warn(vd, "don't know how to transfer from %d to SMPTE ST 2084", src_transfer);
-                break;
-            default:
-                msg_Warn(vd, "don't know how to transfer from %d to %d", src_transfer, display->colorspace->transfer);
-                break;
-        }
-    }
-
-    int range_adjust = 0;
-    if (display->colorspace->b_full_range) {
-        if (!src_full_range)
-            range_adjust = 1; /* raise the source to full range */
-    } else {
-        if (src_full_range)
-            range_adjust = -1; /* lower the source to studio range */
-    }
-    if (!IsRGBShader(format) && !src_full_range)
-        range_adjust--; /* the YUV->RGB conversion already output full range */
-
-    if (range_adjust != 0)
-    {
-        psz_range = malloc(256);
-        if (likely(psz_range))
-        {
-            FLOAT itu_black_level;
-            FLOAT itu_range_factor;
-            FLOAT itu_white_level;
-            switch (format->bitsPerChannel)
-            {
-            case 8:
-                /* Rec. ITU-R BT.709-6 §4.6 */
-                itu_black_level  =              16.f / 255.f;
-                itu_white_level  =             235.f / 255.f;
-                itu_range_factor = (float)(235 - 16) / 255.f;
-                break;
-            case 10:
-                /* Rec. ITU-R BT.709-6 §4.6 */
-                itu_black_level  =              64.f / 1023.f;
-                itu_white_level  =             940.f / 1023.f;
-                itu_range_factor = (float)(940 - 64) / 1023.f;
-                break;
-            case 12:
-                /* Rec. ITU-R BT.2020-2 Table 5 */
-                itu_black_level  =               256.f / 4095.f;
-                itu_white_level  =              3760.f / 4095.f;
-                itu_range_factor = (float)(3760 - 256) / 4095.f;
-                break;
-            default:
-                /* unknown bitdepth, use approximation for infinite bit depth */
-                itu_black_level  =              16.f / 256.f;
-                itu_white_level  =             235.f / 256.f;
-                itu_range_factor = (float)(235 - 16) / 256.f;
-                break;
-            }
-
-            FLOAT black_level = 0;
-            FLOAT range_factor = 1.0f;
-            if (range_adjust > 0)
-            {
-                /* expand the range from studio to full range */
-                while (range_adjust--)
-                {
-                    black_level -= itu_black_level;
-                    range_factor /= itu_range_factor;
-                }
-                sprintf(psz_range, "return max(0,min(1,(rgb + %f) * %f))",
-                        black_level, range_factor);
-            }
-            else
-            {
-                /* shrink the range to studio range */
-                while (range_adjust++)
-                {
-                    black_level += itu_black_level;
-                    range_factor *= itu_range_factor;
-                }
-                sprintf(psz_range, "return clamp(rgb + %f * %f,%f,%f)",
-                        black_level, range_factor, itu_black_level, itu_white_level);
-            }
-            psz_adjust_range = psz_range;
-        }
-    }
-
-    char *shader = malloc(strlen(globPixelShaderDefault) + 32 + strlen(psz_sampler) +
-                          strlen(psz_src_transform) + strlen(psz_display_transform) +
-                          strlen(psz_tone_mapping) + strlen(psz_adjust_range));
-    if (!shader)
-    {
-        msg_Err(vd, "no room for the Pixel Shader");
-        free(psz_range);
-        return E_OUTOFMEMORY;
-    }
-    sprintf(shader, globPixelShaderDefault, legacy_shader ? "" : "Array", psz_src_transform,
-            psz_display_transform, psz_tone_mapping, psz_adjust_range, psz_sampler);
-#ifndef NDEBUG
-    if (!IsRGBShader(format)) {
-        msg_Dbg(vd,"psz_src_transform %s", psz_src_transform);
-        msg_Dbg(vd,"psz_tone_mapping %s", psz_tone_mapping);
-        msg_Dbg(vd,"psz_display_transform %s", psz_display_transform);
-        msg_Dbg(vd,"psz_adjust_range %s", psz_adjust_range);
-        msg_Dbg(vd,"psz_sampler %s", psz_sampler);
-    }
-#endif
-    free(psz_range);
-
-    ID3DBlob *pPSBlob = D3D11_CompileShader(vd, hd3d, d3d_dev, shader, true);
-    free(shader);
-    if (!pPSBlob)
-        return E_INVALIDARG;
-
-    HRESULT hr = ID3D11Device_CreatePixelShader(d3d_dev->d3ddevice,
-                                                (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
-                                                ID3D10Blob_GetBufferSize(pPSBlob), NULL, output);
-
-    ID3D10Blob_Release(pPSBlob);
-    return hr;
-}
-
 static bool CanUseTextureArray(vout_display_t *vd)
 {
 #ifndef HAVE_ID3D11VIDEODECODER
@@ -1933,7 +1564,7 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
 
     sys->legacy_shader = sys->d3d_dev.feature_level < D3D_FEATURE_LEVEL_10_0 || !CanUseTextureArray(vd);
 
-    hr = D3D11_CompilePixelShader(VLC_OBJECT(vd), &sys->hd3d, sys->legacy_shader, &sys->d3d_dev,
+    hr = D3D11_CompilePixelShader(vd, &sys->hd3d, sys->legacy_shader, &sys->d3d_dev,
                                   sys->picQuadConfig, &sys->display, fmt->transfer, fmt->b_color_range_full, &sys->picQuadPixelShader);
     if (FAILED(hr))
     {
@@ -2056,7 +1687,7 @@ static int Direct3D11CreateGenericResources(vout_display_t *vd)
 
     if (sys->d3dregion_format != NULL)
     {
-        hr = D3D11_CompilePixelShader(VLC_OBJECT(vd), &sys->hd3d, sys->legacy_shader, &sys->d3d_dev,
+        hr = D3D11_CompilePixelShader(vd, &sys->hd3d, sys->legacy_shader, &sys->d3d_dev,
                                       sys->d3dregion_format, &sys->display, TRANSFER_FUNC_SRGB, true, &sys->pSPUPixelShader);
         if (FAILED(hr))
         {



More information about the vlc-commits mailing list