mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-02-16 02:30:52 +00:00
Handle chroma co-siting in the D3D11 shaders
This commit is contained in:
@@ -91,9 +91,7 @@
|
||||
<file alias="egl_overlay.vert">shaders/egl_overlay.vert</file>
|
||||
<file alias="d3d11_vertex.fxc">shaders/d3d11_vertex.fxc</file>
|
||||
<file alias="d3d11_overlay_pixel.fxc">shaders/d3d11_overlay_pixel.fxc</file>
|
||||
<file alias="d3d11_genyuv_pixel.fxc">shaders/d3d11_genyuv_pixel.fxc</file>
|
||||
<file alias="d3d11_bt601lim_pixel.fxc">shaders/d3d11_bt601lim_pixel.fxc</file>
|
||||
<file alias="d3d11_bt2020lim_pixel.fxc">shaders/d3d11_bt2020lim_pixel.fxc</file>
|
||||
<file alias="d3d11_yuv420_pixel.fxc">shaders/d3d11_yuv420_pixel.fxc</file>
|
||||
<file alias="d3d11_ayuv_pixel.fxc">shaders/d3d11_ayuv_pixel.fxc</file>
|
||||
<file alias="d3d11_y410_pixel.fxc">shaders/d3d11_y410_pixel.fxc</file>
|
||||
<file alias="vt_renderer.metal">shaders/vt_renderer.metal</file>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
fxc /T vs_4_0_level_9_3 /Fo d3d11_vertex.fxc d3d11_vertex.hlsl
|
||||
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_overlay_pixel.fxc d3d11_overlay_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_genyuv_pixel.fxc d3d11_genyuv_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_bt601lim_pixel.fxc d3d11_bt601lim_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_bt2020lim_pixel.fxc d3d11_bt2020lim_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_yuv420_pixel.fxc d3d11_yuv420_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_ayuv_pixel.fxc d3d11_ayuv_pixel.hlsl
|
||||
fxc /T ps_4_0_level_9_3 /Fo d3d11_y410_pixel.fxc d3d11_y410_pixel.hlsl
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,15 +0,0 @@
|
||||
#include "d3d11_video_pixel_start.hlsli"
|
||||
|
||||
static const min16float3x3 cscMatrix =
|
||||
{
|
||||
1.1678, 1.1678, 1.1678,
|
||||
0.0, -0.1879, 2.1481,
|
||||
1.6836, -0.6524, 0.0,
|
||||
};
|
||||
|
||||
static const min16float3 offsets =
|
||||
{
|
||||
64.0 / 1023.0, 512.0 / 1023.0, 512.0 / 1023.0
|
||||
};
|
||||
|
||||
#include "d3d11_video_pixel_end.hlsli"
|
||||
Binary file not shown.
@@ -1,15 +0,0 @@
|
||||
#include "d3d11_video_pixel_start.hlsli"
|
||||
|
||||
static const min16float3x3 cscMatrix =
|
||||
{
|
||||
1.1644, 1.1644, 1.1644,
|
||||
0.0, -0.3917, 2.0172,
|
||||
1.5960, -0.8129, 0.0,
|
||||
};
|
||||
|
||||
static const min16float3 offsets =
|
||||
{
|
||||
16.0 / 255.0, 128.0 / 255.0, 128.0 / 255.0
|
||||
};
|
||||
|
||||
#include "d3d11_video_pixel_end.hlsli"
|
||||
Binary file not shown.
@@ -2,7 +2,7 @@ min16float4 main(ShaderInput input) : SV_TARGET
|
||||
{
|
||||
// Clamp the chrominance texcoords to avoid sampling the row of texels adjacent to the alignment padding
|
||||
min16float3 yuv = min16float3(luminancePlane.Sample(theSampler, input.tex),
|
||||
chrominancePlane.Sample(theSampler, min(input.tex, chromaTexMax.rg)));
|
||||
chrominancePlane.Sample(theSampler, min(input.tex + chromaOffset, chromaTexMax.rg)));
|
||||
|
||||
// Subtract the YUV offset for limited vs full range
|
||||
yuv -= offsets;
|
||||
|
||||
Binary file not shown.
BIN
app/shaders/d3d11_yuv420_pixel.fxc
Normal file
BIN
app/shaders/d3d11_yuv420_pixel.fxc
Normal file
Binary file not shown.
@@ -4,6 +4,7 @@ cbuffer CSC_CONST_BUF : register(b1)
|
||||
{
|
||||
min16float3x3 cscMatrix;
|
||||
min16float3 offsets;
|
||||
min16float2 chromaOffset;
|
||||
};
|
||||
|
||||
#include "d3d11_video_pixel_end.hlsli"
|
||||
@@ -16,4 +16,5 @@ cbuffer CSC_CONST_BUF : register(b1)
|
||||
{
|
||||
min16float3x3 cscMatrix;
|
||||
min16float3 offsets;
|
||||
min16float2 chromaOffset; // Unused for 4:4:4
|
||||
};
|
||||
@@ -54,16 +54,20 @@ typedef struct _CSC_CONST_BUF
|
||||
// YUV offset values
|
||||
float offsets[OFFSETS_ELEMENT_COUNT];
|
||||
|
||||
// Padding float to be a multiple of 16 bytes
|
||||
// Padding float to end 16-byte boundary
|
||||
float padding;
|
||||
|
||||
// Chroma offset values
|
||||
float chromaOffset[2];
|
||||
|
||||
// Padding to final 16-byte boundary
|
||||
float padding2[2];
|
||||
} CSC_CONST_BUF, *PCSC_CONST_BUF;
|
||||
static_assert(sizeof(CSC_CONST_BUF) % 16 == 0, "Constant buffer sizes must be a multiple of 16");
|
||||
|
||||
static const std::array<const char*, D3D11VARenderer::PixelShaders::_COUNT> k_VideoShaderNames =
|
||||
{
|
||||
"d3d11_genyuv_pixel.fxc",
|
||||
"d3d11_bt601lim_pixel.fxc",
|
||||
"d3d11_bt2020lim_pixel.fxc",
|
||||
"d3d11_yuv420_pixel.fxc",
|
||||
"d3d11_ayuv_pixel.fxc",
|
||||
"d3d11_y410_pixel.fxc",
|
||||
};
|
||||
@@ -541,6 +545,8 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
|
||||
D3D11_TEXTURE2D_DESC textureDesc;
|
||||
d3d11vaFramesContext->texture_infos->texture->GetDesc(&textureDesc);
|
||||
m_TextureFormat = textureDesc.Format;
|
||||
m_TextureWidth = textureDesc.Width;
|
||||
m_TextureHeight = textureDesc.Height;
|
||||
|
||||
if (m_BindDecoderOutputTextures) {
|
||||
// Create SRVs for all textures in the decoder pool
|
||||
@@ -705,14 +711,6 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
bool yuv444 = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_YUV444);
|
||||
int bits = (colorspace == COLORSPACE_REC_2020) ? 10 : 8;
|
||||
|
||||
// We have purpose-built shaders for the common Rec 601 (SDR) and Rec 2020 (HDR) YUV 4:2:0 cases
|
||||
if (!yuv444 && !fullRange && colorspace == COLORSPACE_REC_601) {
|
||||
m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::BT_601_LIMITED_YUV_420].Get(), nullptr, 0);
|
||||
}
|
||||
else if (!yuv444 && !fullRange && colorspace == COLORSPACE_REC_2020) {
|
||||
m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::BT_2020_LIMITED_YUV_420].Get(), nullptr, 0);
|
||||
}
|
||||
else {
|
||||
if (yuv444) {
|
||||
// We'll need to use one of the 4:4:4 shaders for this pixel format
|
||||
switch (m_TextureFormat)
|
||||
@@ -737,13 +735,6 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!yuv444) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Falling back to generic video pixel shader for %d (%s range)",
|
||||
colorspace,
|
||||
fullRange ? "full" : "limited");
|
||||
}
|
||||
|
||||
D3D11_BUFFER_DESC constDesc = {};
|
||||
constDesc.ByteWidth = sizeof(CSC_CONST_BUF);
|
||||
constDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
@@ -792,6 +783,45 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
}
|
||||
}
|
||||
|
||||
switch (frame->chroma_location) {
|
||||
default:
|
||||
case AVCHROMA_LOC_LEFT:
|
||||
constBuf.chromaOffset[0] = 0;
|
||||
constBuf.chromaOffset[1] = 0.5;
|
||||
break;
|
||||
case AVCHROMA_LOC_CENTER:
|
||||
constBuf.chromaOffset[0] = 0.5;
|
||||
constBuf.chromaOffset[1] = 0.5;
|
||||
break;
|
||||
case AVCHROMA_LOC_TOPLEFT:
|
||||
constBuf.chromaOffset[0] = 0;
|
||||
constBuf.chromaOffset[1] = 0;
|
||||
break;
|
||||
case AVCHROMA_LOC_TOP:
|
||||
constBuf.chromaOffset[0] = 0.5;
|
||||
constBuf.chromaOffset[1] = 0;
|
||||
break;
|
||||
case AVCHROMA_LOC_BOTTOMLEFT:
|
||||
constBuf.chromaOffset[0] = 0;
|
||||
constBuf.chromaOffset[1] = 1.0;
|
||||
break;
|
||||
case AVCHROMA_LOC_BOTTOM:
|
||||
constBuf.chromaOffset[0] = 0.5;
|
||||
constBuf.chromaOffset[1] = 1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (yuv444) {
|
||||
// 4:4:4 has no subsampling
|
||||
constBuf.chromaOffset[0] = 0;
|
||||
constBuf.chromaOffset[1] = 0;
|
||||
}
|
||||
else {
|
||||
// 4:2:0 has 2x2 subsampling
|
||||
constBuf.chromaOffset[0] /= m_TextureWidth / 2;
|
||||
constBuf.chromaOffset[1] /= m_TextureHeight / 2;
|
||||
}
|
||||
|
||||
D3D11_SUBRESOURCE_DATA constData = {};
|
||||
constData.pSysMem = &constBuf;
|
||||
|
||||
@@ -806,7 +836,6 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_LastColorSpace = colorspace;
|
||||
m_LastFullRange = fullRange;
|
||||
|
||||
@@ -28,8 +28,6 @@ public:
|
||||
|
||||
enum PixelShaders {
|
||||
GENERIC_YUV_420,
|
||||
BT_601_LIMITED_YUV_420,
|
||||
BT_2020_LIMITED_YUV_420,
|
||||
GENERIC_AYUV,
|
||||
GENERIC_Y410,
|
||||
_COUNT
|
||||
@@ -72,6 +70,8 @@ private:
|
||||
DECODER_PARAMETERS m_DecoderParams;
|
||||
int m_TextureAlignment;
|
||||
DXGI_FORMAT m_TextureFormat;
|
||||
UINT m_TextureWidth;
|
||||
UINT m_TextureHeight;
|
||||
int m_DisplayWidth;
|
||||
int m_DisplayHeight;
|
||||
int m_LastColorSpace;
|
||||
|
||||
Reference in New Issue
Block a user