1 /*****************************************************************************
2 * d3d11_shaders.c: Direct3D11 Shaders
3 *****************************************************************************
4 * Copyright (C) 2017 VLC authors and VideoLAN
6 * Authors: Steve Lhomme <robux4@gmail.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < _WIN32_WINNT_WIN7
25 # define _WIN32_WINNT _WIN32_WINNT_WIN7
32 #include <vlc_common.h>
39 #include "d3d11_shaders.h"
42 # define D3DCompile(args...) hd3d->OurD3DCompile(args)
45 #define ST2084_PQ_CONSTANTS "const float ST2084_m1 = 2610.0 / (4096.0 * 4);\n\
46 const float ST2084_m2 = (2523.0 / 4096.0) * 128.0;\n\
47 const float ST2084_c1 = 3424.0 / 4096.0;\n\
48 const float ST2084_c2 = (2413.0 / 4096.0) * 32.0;\n\
49 const float ST2084_c3 = (2392.0 / 4096.0) * 32.0;\n"
51 #define STRINGIZE2(s) #s
52 #define STRINGIZE(s) STRINGIZE2(s)
54 static const char* globPixelShaderDefault
= "\
55 cbuffer PS_CONSTANT_BUFFER : register(b0)\n\
60 float LuminanceScale;\n\
62 cbuffer PS_COLOR_TRANSFORM : register(b1)\n\
64 float4x4 WhitePoint;\n\
65 float4x4 Colorspace;\n\
66 float3x3 Primaries;\n\
68 Texture2D%s shaderTexture[" STRINGIZE(D3D11_MAX_SHADER_VIEW
) "];\n\
69 SamplerState SamplerStates[2];\n\
73 float4 Position : SV_POSITION;\n\
74 float3 Texture : TEXCOORD0;\n\
77 /* see http://filmicworlds.com/blog/filmic-tonemapping-operators/ */\n\
78 inline float3 hable(float3 x) {\n\
79 const float A = 0.15, B = 0.50, C = 0.10, D = 0.20, E = 0.02, F = 0.30;\n\
80 return ((x * (A*x + (C*B))+(D*E))/(x * (A*x + B) + (D*F))) - E/F;\n\
83 /* https://en.wikipedia.org/wiki/Hybrid_Log-Gamma#Technical_details */\n\
84 inline float inverse_HLG(float x){\n\
85 const float B67_a = 0.17883277;\n\
86 const float B67_b = 0.28466892;\n\
87 const float B67_c = 0.55991073;\n\
88 const float B67_inv_r2 = 4.0; /* 1/0.5² */\n\
90 x = x * x * B67_inv_r2;\n\
92 x = exp((x - B67_c) / B67_a) + B67_b;\n\
96 inline float3 sourceToLinear(float3 rgb) {\n\
100 inline float3 linearToDisplay(float3 rgb) {\n\
104 inline float3 transformPrimaries(float3 rgb) {\n\
108 inline float3 toneMapping(float3 rgb) {\n\
112 inline float3 adjustRange(float3 rgb) {\n\
116 inline float3 reorderPlanes(float3 rgb) {\n\
120 inline float4 sampleTexture(SamplerState samplerState, float3 coords) {\n\
122 %s /* sampling routine in sample */\n\
126 float4 main( PS_INPUT In ) : SV_TARGET\n\
130 if (In.Texture.x > BoundaryX || In.Texture.y > BoundaryY) \n\
131 sample = sampleTexture( SamplerStates[1], In.Texture );\n\
133 sample = sampleTexture( SamplerStates[0], In.Texture );\n\
134 float4 rgba = mul(mul(sample, WhitePoint), Colorspace);\n\
135 float opacity = rgba.a * Opacity;\n\
136 float3 rgb = (float3)rgba;\n\
137 rgb = sourceToLinear(rgb);\n\
138 rgb = transformPrimaries(rgb);\n\
139 rgb = toneMapping(rgb);\n\
140 rgb = linearToDisplay(rgb);\n\
141 rgb = adjustRange(rgb);\n\
142 rgb = reorderPlanes(rgb);\n\
143 return float4(rgb, saturate(opacity));\n\
147 const char* globVertexShaderFlat
= "\
150 float4 Position : POSITION;\n\
151 float4 Texture : TEXCOORD0;\n\
156 float4 Position : SV_POSITION;\n\
157 float4 Texture : TEXCOORD0;\n\
160 VS_OUTPUT main( VS_INPUT In )\n\
166 const char* globVertexShaderProjection
= "\n\
167 cbuffer VS_PROJECTION_CONST : register(b0)\n\
173 float4x4 Projection;\n\
177 float4 Position : POSITION;\n\
178 float4 Texture : TEXCOORD0;\n\
183 float4 Position : SV_POSITION;\n\
184 float4 Texture : TEXCOORD0;\n\
187 VS_OUTPUT main( VS_INPUT In )\n\
190 float4 pos = In.Position;\n\
191 pos = mul(RotY, pos);\n\
192 pos = mul(RotX, pos);\n\
193 pos = mul(RotZ, pos);\n\
194 pos = mul(View, pos);\n\
195 pos = mul(Projection, pos);\n\
196 Output.Position = pos;\n\
197 Output.Texture = In.Texture;\n\
202 bool IsRGBShader(const d3d_format_t
*cfg
)
204 return cfg
->resourceFormat
[0] != DXGI_FORMAT_R8_UNORM
&&
205 cfg
->resourceFormat
[0] != DXGI_FORMAT_R16_UNORM
&&
206 cfg
->formatTexture
!= DXGI_FORMAT_YUY2
;
209 static HRESULT
CompileTargetShader(vlc_object_t
*o
, d3d11_handle_t
*hd3d
, bool legacy_shader
,
210 d3d11_device_t
*d3d_dev
,
211 const char *psz_sampler
,
212 const char *psz_src_transform
,
213 const char *psz_primaries_transform
,
214 const char *psz_display_transform
,
215 const char *psz_tone_mapping
,
216 const char *psz_adjust_range
, const char *psz_move_planes
,
217 ID3D11PixelShader
**output
)
219 char *shader
= malloc(strlen(globPixelShaderDefault
) + 32 + strlen(psz_sampler
) +
220 strlen(psz_src_transform
) + strlen(psz_primaries_transform
) + strlen(psz_display_transform
) +
221 strlen(psz_tone_mapping
) + strlen(psz_adjust_range
) + strlen(psz_move_planes
));
224 msg_Err(o
, "no room for the Pixel Shader");
225 return E_OUTOFMEMORY
;
227 sprintf(shader
, globPixelShaderDefault
, legacy_shader
? "" : "Array", psz_src_transform
,
228 psz_display_transform
, psz_primaries_transform
, psz_tone_mapping
,
229 psz_adjust_range
, psz_move_planes
, psz_sampler
);
230 if (var_InheritInteger(o
, "verbose") >= 4)
231 msg_Dbg(o
, "shader %s", shader
);
234 msg_Dbg(o
,"psz_src_transform %s", psz_src_transform
);
235 msg_Dbg(o
,"psz_primaries_transform %s", psz_primaries_transform
);
236 msg_Dbg(o
,"psz_tone_mapping %s", psz_tone_mapping
);
237 msg_Dbg(o
,"psz_display_transform %s", psz_display_transform
);
238 msg_Dbg(o
,"psz_adjust_range %s", psz_adjust_range
);
239 msg_Dbg(o
,"psz_sampler %s", psz_sampler
);
240 msg_Dbg(o
,"psz_move_planes %s", psz_move_planes
);
244 ID3DBlob
*pPSBlob
= D3D11_CompileShader(o
, hd3d
, d3d_dev
, shader
, true);
249 HRESULT hr
= ID3D11Device_CreatePixelShader(d3d_dev
->d3ddevice
,
250 (void *)ID3D10Blob_GetBufferPointer(pPSBlob
),
251 ID3D10Blob_GetBufferSize(pPSBlob
), NULL
, output
);
253 ID3D10Blob_Release(pPSBlob
);
257 #undef D3D11_CompilePixelShader
258 HRESULT
D3D11_CompilePixelShader(vlc_object_t
*o
, d3d11_handle_t
*hd3d
, bool legacy_shader
,
259 d3d11_device_t
*d3d_dev
,
260 const display_info_t
*display
,
261 video_transfer_func_t transfer
,
262 video_color_primaries_t primaries
, bool src_full_range
,
265 static const char *DEFAULT_NOOP
= "return rgb";
266 const char *psz_sampler
[2] = {NULL
, NULL
};
267 const char *psz_src_transform
= DEFAULT_NOOP
;
268 const char *psz_display_transform
= DEFAULT_NOOP
;
269 const char *psz_primaries_transform
= DEFAULT_NOOP
;
270 const char *psz_tone_mapping
= DEFAULT_NOOP
;
271 const char *psz_adjust_range
= DEFAULT_NOOP
;
272 const char *psz_move_planes
[2] = {DEFAULT_NOOP
, DEFAULT_NOOP
};
273 char *psz_range
= NULL
;
275 D3D11_SAMPLER_DESC sampDesc
;
276 memset(&sampDesc
, 0, sizeof(sampDesc
));
277 sampDesc
.Filter
= D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT
;
278 sampDesc
.AddressU
= D3D11_TEXTURE_ADDRESS_CLAMP
;
279 sampDesc
.AddressV
= D3D11_TEXTURE_ADDRESS_CLAMP
;
280 sampDesc
.AddressW
= D3D11_TEXTURE_ADDRESS_CLAMP
;
281 sampDesc
.ComparisonFunc
= D3D11_COMPARISON_ALWAYS
;
283 sampDesc
.MaxLOD
= D3D11_FLOAT32_MAX
;
286 hr
= ID3D11Device_CreateSamplerState(d3d_dev
->d3ddevice
, &sampDesc
, &quad
->d3dsampState
[0]);
288 msg_Err(o
, "Could not Create the D3d11 Sampler State. (hr=0x%lX)", hr
);
292 sampDesc
.Filter
= D3D11_FILTER_MIN_MAG_MIP_POINT
;
293 hr
= ID3D11Device_CreateSamplerState(d3d_dev
->d3ddevice
, &sampDesc
, &quad
->d3dsampState
[1]);
295 msg_Err(o
, "Could not Create the D3d11 Sampler State. (hr=0x%lX)", hr
);
296 ID3D11SamplerState_Release(quad
->d3dsampState
[0]);
300 if ( display
->pixelFormat
->formatTexture
== DXGI_FORMAT_NV12
||
301 display
->pixelFormat
->formatTexture
== DXGI_FORMAT_P010
)
303 /* we need 2 shaders, one for the Y target, one for the UV target */
304 switch (quad
->textureFormat
->formatTexture
)
306 case DXGI_FORMAT_NV12
:
307 case DXGI_FORMAT_P010
:
309 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
314 "sample.xy = shaderTexture[1].Sample(samplerState, coords).xy;\n"
318 case DXGI_FORMAT_R8G8B8A8_UNORM
:
319 case DXGI_FORMAT_B8G8R8A8_UNORM
:
320 case DXGI_FORMAT_B8G8R8X8_UNORM
:
321 case DXGI_FORMAT_R10G10B10A2_UNORM
:
322 case DXGI_FORMAT_R16G16B16A16_UNORM
:
323 case DXGI_FORMAT_B5G6R5_UNORM
:
326 "sample = shaderTexture[0].Sample(samplerState, coords);\n";
327 psz_move_planes
[0] = "return rgb";
330 "sample = shaderTexture[0].Sample(samplerState, coords);\n";
337 case DXGI_FORMAT_UNKNOWN
:
338 switch (quad
->textureFormat
->fourcc
)
343 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
346 "sample.a = shaderTexture[3].Sample(samplerState, coords).x;";
349 "sample.x = shaderTexture[1].Sample(samplerState, coords).x;\n"
350 "sample.y = shaderTexture[2].Sample(samplerState, coords).x;\n"
352 "sample.a = shaderTexture[3].Sample(samplerState, coords).x;";
355 vlc_assert_unreachable();
359 vlc_assert_unreachable();
364 switch (quad
->textureFormat
->formatTexture
)
366 case DXGI_FORMAT_NV12
:
367 case DXGI_FORMAT_P010
:
369 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
370 "sample.yz = shaderTexture[1].Sample(samplerState, coords).xy;\n"
373 case DXGI_FORMAT_YUY2
:
375 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
376 "sample.y = shaderTexture[0].Sample(samplerState, coords).y;\n"
377 "sample.z = shaderTexture[0].Sample(samplerState, coords).a;\n"
380 case DXGI_FORMAT_AYUV
:
382 "sample.x = shaderTexture[0].Sample(SampleType, coords).z;\n"
383 "sample.y = shaderTexture[0].Sample(SampleType, coords).y;\n"
384 "sample.z = shaderTexture[0].Sample(SampleType, coords).x;\n"
385 "sample.a = shaderTexture[0].Sample(SampleType, coords).a;";
387 case DXGI_FORMAT_R8G8B8A8_UNORM
:
388 case DXGI_FORMAT_B8G8R8A8_UNORM
:
389 case DXGI_FORMAT_B8G8R8X8_UNORM
:
390 case DXGI_FORMAT_R10G10B10A2_UNORM
:
391 case DXGI_FORMAT_R16G16B16A16_UNORM
:
392 case DXGI_FORMAT_B5G6R5_UNORM
:
394 "sample = shaderTexture[0].Sample(samplerState, coords);";
396 case DXGI_FORMAT_UNKNOWN
:
397 switch (quad
->textureFormat
->fourcc
)
399 case VLC_CODEC_I420_10L
:
401 "sample.x = shaderTexture[0].Sample(samplerState, coords).x * 64;\n"
402 "sample.y = shaderTexture[1].Sample(samplerState, coords).x * 64;\n"
403 "sample.z = shaderTexture[2].Sample(samplerState, coords).x * 64;\n"
408 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
409 "sample.y = shaderTexture[1].Sample(samplerState, coords).x;\n"
410 "sample.z = shaderTexture[2].Sample(samplerState, coords).x;\n"
415 "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
416 "sample.y = shaderTexture[1].Sample(samplerState, coords).x;\n"
417 "sample.z = shaderTexture[2].Sample(samplerState, coords).x;\n"
418 "sample.a = shaderTexture[3].Sample(samplerState, coords).x;";
421 vlc_assert_unreachable();
425 vlc_assert_unreachable();
429 video_transfer_func_t src_transfer
;
431 if (transfer
!= display
->colorspace
->transfer
)
433 /* we need to go in linear mode */
436 case TRANSFER_FUNC_SMPTE_ST2084
:
437 /* ST2084 to Linear */
440 "rgb = pow(rgb, 1.0/ST2084_m2);\n"
441 "rgb = max(rgb - ST2084_c1, 0.0) / (ST2084_c2 - ST2084_c3 * rgb);\n"
442 "rgb = pow(rgb, 1.0/ST2084_m1);\n"
444 src_transfer
= TRANSFER_FUNC_LINEAR
;
446 case TRANSFER_FUNC_HLG
:
449 "rgb.r = inverse_HLG(rgb.r);\n"
450 "rgb.g = inverse_HLG(rgb.g);\n"
451 "rgb.b = inverse_HLG(rgb.b);\n"
453 src_transfer
= TRANSFER_FUNC_LINEAR
;
455 case TRANSFER_FUNC_BT709
:
456 psz_src_transform
= "return pow(rgb, 1.0 / 0.45)";
457 src_transfer
= TRANSFER_FUNC_LINEAR
;
459 case TRANSFER_FUNC_BT470_M
:
460 case TRANSFER_FUNC_SRGB
:
461 psz_src_transform
= "return pow(rgb, 2.2)";
462 src_transfer
= TRANSFER_FUNC_LINEAR
;
464 case TRANSFER_FUNC_BT470_BG
:
465 psz_src_transform
= "return pow(rgb, 2.8)";
466 src_transfer
= TRANSFER_FUNC_LINEAR
;
469 msg_Dbg(o
, "unhandled source transfer %d", transfer
);
470 src_transfer
= transfer
;
474 switch (display
->colorspace
->transfer
)
476 case TRANSFER_FUNC_SRGB
:
477 if (src_transfer
== TRANSFER_FUNC_LINEAR
)
480 psz_display_transform
= "return pow(rgb, 1.0 / 2.2)";
482 if (transfer
== TRANSFER_FUNC_SMPTE_ST2084
|| transfer
== TRANSFER_FUNC_HLG
)
484 /* HDR tone mapping */
486 "static const float3 HABLE_DIV = hable(11.2);\n"
487 "rgb = hable(rgb * LuminanceScale) / HABLE_DIV;\n"
492 msg_Warn(o
, "don't know how to transfer from %d to sRGB", src_transfer
);
495 case TRANSFER_FUNC_SMPTE_ST2084
:
496 if (src_transfer
== TRANSFER_FUNC_LINEAR
)
498 /* Linear to ST2084 */
499 psz_display_transform
=
501 "rgb = pow(rgb, ST2084_m1);\n"
502 "rgb = (ST2084_c1 + ST2084_c2 * rgb) / (1 + ST2084_c3 * rgb);\n"
503 "rgb = pow(rgb, ST2084_m2);\n"
507 msg_Warn(o
, "don't know how to transfer from %d to SMPTE ST 2084", src_transfer
);
510 msg_Warn(o
, "don't know how to transfer from %d to %d", src_transfer
, display
->colorspace
->transfer
);
515 int range_adjust
= 0;
516 if (display
->colorspace
->b_full_range
) {
518 range_adjust
= 1; /* raise the source to full range */
521 range_adjust
= -1; /* lower the source to studio range */
523 if (!IsRGBShader(quad
->textureFormat
) && !src_full_range
)
524 range_adjust
--; /* the YUV->RGB conversion already output full range */
526 if (range_adjust
!= 0)
528 psz_range
= malloc(256);
529 if (likely(psz_range
))
531 FLOAT itu_black_level
;
532 FLOAT itu_range_factor
;
533 FLOAT itu_white_level
;
534 switch (quad
->textureFormat
->bitsPerChannel
)
537 /* Rec. ITU-R BT.709-6 §4.6 */
538 itu_black_level
= 16.f
/ 255.f
;
539 itu_white_level
= 235.f
/ 255.f
;
540 itu_range_factor
= (float)(235 - 16) / 255.f
;
543 /* Rec. ITU-R BT.709-6 §4.6 */
544 itu_black_level
= 64.f
/ 1023.f
;
545 itu_white_level
= 940.f
/ 1023.f
;
546 itu_range_factor
= (float)(940 - 64) / 1023.f
;
549 /* Rec. ITU-R BT.2020-2 Table 5 */
550 itu_black_level
= 256.f
/ 4095.f
;
551 itu_white_level
= 3760.f
/ 4095.f
;
552 itu_range_factor
= (float)(3760 - 256) / 4095.f
;
555 /* unknown bitdepth, use approximation for infinite bit depth */
556 itu_black_level
= 16.f
/ 256.f
;
557 itu_white_level
= 235.f
/ 256.f
;
558 itu_range_factor
= (float)(235 - 16) / 256.f
;
562 FLOAT black_level
= 0;
563 FLOAT range_factor
= 1.0f
;
564 if (range_adjust
> 0)
566 /* expand the range from studio to full range */
567 while (range_adjust
--)
569 black_level
-= itu_black_level
;
570 range_factor
/= itu_range_factor
;
572 sprintf(psz_range
, "return max(0,min(1,(rgb + %f) * %f))",
573 black_level
, range_factor
);
577 /* shrink the range to studio range */
578 while (range_adjust
++)
580 black_level
+= itu_black_level
;
581 range_factor
*= itu_range_factor
;
583 sprintf(psz_range
, "return clamp(rgb + %f * %f,%f,%f)",
584 black_level
, range_factor
, itu_black_level
, itu_white_level
);
586 psz_adjust_range
= psz_range
;
590 hr
= CompileTargetShader(o
, hd3d
, legacy_shader
, d3d_dev
,
591 psz_sampler
[0], psz_src_transform
,
592 psz_primaries_transform
,
593 psz_display_transform
, psz_tone_mapping
,
594 psz_adjust_range
, psz_move_planes
[0], &quad
->d3dpixelShader
[0]);
595 if (!FAILED(hr
) && psz_sampler
[1])
596 hr
= CompileTargetShader(o
, hd3d
, legacy_shader
, d3d_dev
,
597 psz_sampler
[1], psz_src_transform
,
598 psz_primaries_transform
,
599 psz_display_transform
, psz_tone_mapping
,
600 psz_adjust_range
, psz_move_planes
[1], &quad
->d3dpixelShader
[1]);
606 void D3D11_ReleasePixelShader(d3d_quad_t
*quad
)
608 for (size_t i
=0; i
<D3D11_MAX_SHADER_VIEW
; i
++)
610 if (quad
->d3dpixelShader
[i
])
612 ID3D11PixelShader_Release(quad
->d3dpixelShader
[i
]);
613 quad
->d3dpixelShader
[i
] = NULL
;
618 #undef D3D11_CompileShader
619 ID3DBlob
* D3D11_CompileShader(vlc_object_t
*obj
, const d3d11_handle_t
*hd3d
, const d3d11_device_t
*d3d_dev
,
620 const char *psz_shader
, bool pixel
)
622 ID3DBlob
* pShaderBlob
= NULL
, *pErrBlob
;
626 if (likely(d3d_dev
->feature_level
>= D3D_FEATURE_LEVEL_10_0
))
628 else if (d3d_dev
->feature_level
>= D3D_FEATURE_LEVEL_9_3
)
629 target
= "ps_4_0_level_9_3";
631 target
= "ps_4_0_level_9_1";
635 if (likely(d3d_dev
->feature_level
>= D3D_FEATURE_LEVEL_10_0
))
637 else if (d3d_dev
->feature_level
>= D3D_FEATURE_LEVEL_9_3
)
638 target
= "vs_4_0_level_9_3";
640 target
= "vs_4_0_level_9_1";
643 HRESULT hr
= D3DCompile(psz_shader
, strlen(psz_shader
),
644 NULL
, NULL
, NULL
, "main", target
,
645 0, 0, &pShaderBlob
, &pErrBlob
);
648 char *err
= pErrBlob
? ID3D10Blob_GetBufferPointer(pErrBlob
) : NULL
;
649 msg_Err(obj
, "invalid %s Shader (hr=0x%lX): %s", pixel
?"Pixel":"Vertex", hr
, err
);
651 ID3D10Blob_Release(pErrBlob
);
657 #undef GetFormatLuminance
658 float GetFormatLuminance(vlc_object_t
*o
, const video_format_t
*fmt
)
660 switch (fmt
->transfer
)
662 case TRANSFER_FUNC_SMPTE_ST2084
:
663 /* that's the default PQ value if the metadata are not set */
664 return MAX_PQ_BRIGHTNESS
;
665 case TRANSFER_FUNC_HLG
:
667 case TRANSFER_FUNC_BT470_BG
:
668 case TRANSFER_FUNC_BT470_M
:
669 case TRANSFER_FUNC_BT709
:
670 case TRANSFER_FUNC_SRGB
:
671 return DEFAULT_BRIGHTNESS
;
673 msg_Dbg(o
, "unhandled source transfer %d", fmt
->transfer
);
674 return DEFAULT_BRIGHTNESS
;
678 HRESULT
D3D11_CreateRenderTargets( d3d11_device_t
*d3d_dev
, ID3D11Resource
*texture
,
679 const d3d_format_t
*cfg
, ID3D11RenderTargetView
*output
[D3D11_MAX_SHADER_VIEW
] )
681 D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc
;
682 renderTargetViewDesc
.ViewDimension
= D3D11_RTV_DIMENSION_TEXTURE2D
;
683 renderTargetViewDesc
.Texture2D
.MipSlice
= 0;
685 for (size_t i
=0; i
<D3D11_MAX_SHADER_VIEW
; i
++)
687 if (cfg
->resourceFormat
[i
])
689 renderTargetViewDesc
.Format
= cfg
->resourceFormat
[i
];
690 HRESULT hr
= ID3D11Device_CreateRenderTargetView(d3d_dev
->d3ddevice
, texture
,
691 &renderTargetViewDesc
, &output
[i
]);
701 void D3D11_ClearRenderTargets(d3d11_device_t
*d3d_dev
, const d3d_format_t
*cfg
,
702 ID3D11RenderTargetView
*targets
[D3D11_MAX_SHADER_VIEW
])
704 static const FLOAT blackY
[1] = {0.0f
};
705 static const FLOAT blackUV
[2] = {0.5f
, 0.5f
};
706 static const FLOAT blackRGBA
[4] = {0.0f
, 0.0f
, 0.0f
, 1.0f
};
707 static const FLOAT blackYUY2
[4] = {0.0f
, 0.5f
, 0.0f
, 0.5f
};
708 static const FLOAT blackVUYA
[4] = {0.5f
, 0.5f
, 0.0f
, 1.0f
};
710 switch (cfg
->formatTexture
)
712 case DXGI_FORMAT_NV12
:
713 case DXGI_FORMAT_P010
:
714 ID3D11DeviceContext_ClearRenderTargetView( d3d_dev
->d3dcontext
, targets
[0], blackY
);
715 ID3D11DeviceContext_ClearRenderTargetView( d3d_dev
->d3dcontext
, targets
[1], blackUV
);
717 case DXGI_FORMAT_R8G8B8A8_UNORM
:
718 case DXGI_FORMAT_B8G8R8A8_UNORM
:
719 case DXGI_FORMAT_B8G8R8X8_UNORM
:
720 case DXGI_FORMAT_R10G10B10A2_UNORM
:
721 case DXGI_FORMAT_B5G6R5_UNORM
:
722 ID3D11DeviceContext_ClearRenderTargetView( d3d_dev
->d3dcontext
, targets
[0], blackRGBA
);
724 case DXGI_FORMAT_YUY2
:
725 ID3D11DeviceContext_ClearRenderTargetView( d3d_dev
->d3dcontext
, targets
[0], blackYUY2
);
727 case DXGI_FORMAT_AYUV
:
728 ID3D11DeviceContext_ClearRenderTargetView( d3d_dev
->d3dcontext
, targets
[0], blackVUYA
);
731 vlc_assert_unreachable();
735 static HRESULT
D3D11_CompileVertexShader(vlc_object_t
*obj
, d3d11_handle_t
*hd3d
,
736 d3d11_device_t
*d3d_dev
, const char *psz_shader
,
737 d3d_vshader_t
*output
)
740 ID3DBlob
*pVSBlob
= D3D11_CompileShader(obj
, hd3d
, d3d_dev
, psz_shader
, false);
744 hr
= ID3D11Device_CreateVertexShader(d3d_dev
->d3ddevice
, (void *)ID3D10Blob_GetBufferPointer(pVSBlob
),
745 ID3D10Blob_GetBufferSize(pVSBlob
), NULL
, &output
->shader
);
748 msg_Err(obj
, "Failed to create the flat vertex shader. (hr=0x%lX)", hr
);
752 static D3D11_INPUT_ELEMENT_DESC layout
[] = {
753 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT
, 0, D3D11_APPEND_ALIGNED_ELEMENT
, D3D11_INPUT_PER_VERTEX_DATA
, 0},
754 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, D3D11_APPEND_ALIGNED_ELEMENT
, D3D11_INPUT_PER_VERTEX_DATA
, 0},
757 hr
= ID3D11Device_CreateInputLayout(d3d_dev
->d3ddevice
, layout
, 2, (void *)ID3D10Blob_GetBufferPointer(pVSBlob
),
758 ID3D10Blob_GetBufferSize(pVSBlob
), &output
->layout
);
760 ID3D10Blob_Release(pVSBlob
);
763 msg_Err(obj
, "Failed to create the vertex input layout. (hr=0x%lX)", hr
);
772 void D3D11_SetVertexShader(d3d_vshader_t
*dst
, d3d_vshader_t
*src
)
774 dst
->layout
= src
->layout
;
775 ID3D11InputLayout_AddRef(dst
->layout
);
776 dst
->shader
= src
->shader
;
777 ID3D11VertexShader_AddRef(dst
->shader
);
780 void D3D11_ReleaseVertexShader(d3d_vshader_t
*shader
)
784 ID3D11InputLayout_Release(shader
->layout
);
785 shader
->layout
= NULL
;
789 ID3D11VertexShader_Release(shader
->shader
);
790 shader
->shader
= NULL
;
794 #undef D3D11_CompileFlatVertexShader
795 HRESULT
D3D11_CompileFlatVertexShader(vlc_object_t
*obj
, d3d11_handle_t
*hd3d
,
796 d3d11_device_t
*d3d_dev
, d3d_vshader_t
*output
)
798 return D3D11_CompileVertexShader(obj
, hd3d
, d3d_dev
, globVertexShaderFlat
, output
);
801 #undef D3D11_CompileProjectionVertexShader
802 HRESULT
D3D11_CompileProjectionVertexShader(vlc_object_t
*obj
, d3d11_handle_t
*hd3d
,
803 d3d11_device_t
*d3d_dev
, d3d_vshader_t
*output
)
805 return D3D11_CompileVertexShader(obj
, hd3d
, d3d_dev
, globVertexShaderProjection
, output
);