diff --git a/app/shaders/d3d11_bt2020lim_pixel.fxc b/app/shaders/d3d11_bt2020lim_pixel.fxc index d557a9ed..b015bbeb 100644 Binary files a/app/shaders/d3d11_bt2020lim_pixel.fxc and b/app/shaders/d3d11_bt2020lim_pixel.fxc differ diff --git a/app/shaders/d3d11_bt601lim_pixel.fxc b/app/shaders/d3d11_bt601lim_pixel.fxc index 702040c5..09f25653 100644 Binary files a/app/shaders/d3d11_bt601lim_pixel.fxc and b/app/shaders/d3d11_bt601lim_pixel.fxc differ diff --git a/app/shaders/d3d11_genyuv_pixel.fxc b/app/shaders/d3d11_genyuv_pixel.fxc index f7fdeb42..7aa73c5e 100644 Binary files a/app/shaders/d3d11_genyuv_pixel.fxc and b/app/shaders/d3d11_genyuv_pixel.fxc differ diff --git a/app/shaders/d3d11_genyuv_pixel.hlsl b/app/shaders/d3d11_genyuv_pixel.hlsl index b2f8a150..ea66df5d 100644 --- a/app/shaders/d3d11_genyuv_pixel.hlsl +++ b/app/shaders/d3d11_genyuv_pixel.hlsl @@ -1,6 +1,6 @@ #include "d3d11_video_pixel_start.hlsli" -cbuffer CSC_CONST_BUF : register(b0) +cbuffer CSC_CONST_BUF : register(b1) { min16float3x3 cscMatrix; min16float3 offsets; diff --git a/app/shaders/d3d11_video_pixel_end.hlsli b/app/shaders/d3d11_video_pixel_end.hlsli index db62c66a..6b7cc26a 100644 --- a/app/shaders/d3d11_video_pixel_end.hlsli +++ b/app/shaders/d3d11_video_pixel_end.hlsli @@ -1,7 +1,8 @@ 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, input.tex)); + chrominancePlane.Sample(theSampler, min(input.tex, chromaTexMax.rg))); // Subtract the YUV offset for limited vs full range yuv -= offsets; diff --git a/app/shaders/d3d11_video_pixel_start.hlsli b/app/shaders/d3d11_video_pixel_start.hlsli index 863d9d43..a148ff98 100644 --- a/app/shaders/d3d11_video_pixel_start.hlsli +++ b/app/shaders/d3d11_video_pixel_start.hlsli @@ -6,4 +6,9 @@ struct ShaderInput { float4 pos : SV_POSITION; float2 tex : TEXCOORD0; -}; \ No newline at end of file +}; + +cbuffer ChromaLimitBuf : register(b0) +{ + min16float3 chromaTexMax; +}; diff --git a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp index 4b209a4c..2fd792e5 100644 --- a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp +++ b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp @@ -728,7 +728,7 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame) ID3D11Buffer* constantBuffer; HRESULT hr = m_Device->CreateBuffer(&constDesc, &constData, &constantBuffer); if (SUCCEEDED(hr)) { - m_DeviceContext->PSSetConstantBuffers(0, 1, &constantBuffer); + m_DeviceContext->PSSetConstantBuffers(1, 1, &constantBuffer); constantBuffer->Release(); } else { @@ -1313,6 +1313,39 @@ bool D3D11VARenderer::setupRenderingResources() } } + // Create our fixed constant buffer to limit chroma texcoords and avoid sampling from alignment texels. + { + D3D11_BUFFER_DESC constDesc = {}; + constDesc.ByteWidth = sizeof(CSC_CONST_BUF); + constDesc.Usage = D3D11_USAGE_IMMUTABLE; + constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constDesc.CPUAccessFlags = 0; + constDesc.MiscFlags = 0; + + int alignedWidth = FFALIGN(m_DecoderParams.width, m_TextureAlignment); + int alignedHeight = FFALIGN(m_DecoderParams.height, m_TextureAlignment); + + float chromaUVMax[3] = {}; + chromaUVMax[0] = m_DecoderParams.width != alignedWidth ? ((float)(m_DecoderParams.width - 1) / alignedWidth) : 1.0f; + chromaUVMax[1] = m_DecoderParams.height != alignedHeight ? ((float)(m_DecoderParams.height - 1) / alignedHeight) : 1.0f; + + D3D11_SUBRESOURCE_DATA constData = {}; + constData.pSysMem = chromaUVMax; + + ID3D11Buffer* constantBuffer; + HRESULT hr = m_Device->CreateBuffer(&constDesc, &constData, &constantBuffer); + if (SUCCEEDED(hr)) { + m_DeviceContext->PSSetConstantBuffers(0, 1, &constantBuffer); + constantBuffer->Release(); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "ID3D11Device::CreateBuffer() failed: %x", + hr); + return false; + } + } + // Create our blend state { D3D11_BLEND_DESC blendDesc = {};