diff --git a/app/resources.qrc b/app/resources.qrc index 88e724a8..e4be65a2 100644 --- a/app/resources.qrc +++ b/app/resources.qrc @@ -86,6 +86,8 @@ shaders/d3d11_genyuv_pixel.fxc shaders/d3d11_bt601lim_pixel.fxc shaders/d3d11_bt2020lim_pixel.fxc + shaders/d3d11_ayuv_pixel.fxc + shaders/d3d11_y410_pixel.fxc shaders/vt_renderer.metal diff --git a/app/shaders/build_hlsl.bat b/app/shaders/build_hlsl.bat index 4a8389ab..8ad73264 100644 --- a/app/shaders/build_hlsl.bat +++ b/app/shaders/build_hlsl.bat @@ -3,4 +3,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 \ No newline at end of file +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_ayuv_pixel.fxc d3d11_ayuv_pixel.hlsl +fxc /T ps_4_0_level_9_3 /Fo d3d11_y410_pixel.fxc d3d11_y410_pixel.hlsl \ No newline at end of file diff --git a/app/shaders/d3d11_ayuv_pixel.fxc b/app/shaders/d3d11_ayuv_pixel.fxc new file mode 100644 index 00000000..e820f23f Binary files /dev/null and b/app/shaders/d3d11_ayuv_pixel.fxc differ diff --git a/app/shaders/d3d11_ayuv_pixel.hlsl b/app/shaders/d3d11_ayuv_pixel.hlsl new file mode 100644 index 00000000..155387ee --- /dev/null +++ b/app/shaders/d3d11_ayuv_pixel.hlsl @@ -0,0 +1,9 @@ +#include "d3d11_yuv444_pixel_start.hlsli" + +min16float3 swizzle(min16float3 input) +{ + // AYUV SRVs are in VUYA order + return input.bgr; +} + +#include "d3d11_yuv444_pixel_end.hlsli" \ No newline at end of file diff --git a/app/shaders/d3d11_y410_pixel.fxc b/app/shaders/d3d11_y410_pixel.fxc new file mode 100644 index 00000000..2365f7c1 Binary files /dev/null and b/app/shaders/d3d11_y410_pixel.fxc differ diff --git a/app/shaders/d3d11_y410_pixel.hlsl b/app/shaders/d3d11_y410_pixel.hlsl new file mode 100644 index 00000000..3480a7f4 --- /dev/null +++ b/app/shaders/d3d11_y410_pixel.hlsl @@ -0,0 +1,9 @@ +#include "d3d11_yuv444_pixel_start.hlsli" + +min16float3 swizzle(min16float3 input) +{ + // Y410 SRVs are in UYVA order + return input.grb; +} + +#include "d3d11_yuv444_pixel_end.hlsli" \ No newline at end of file diff --git a/app/shaders/d3d11_yuv444_pixel_end.hlsli b/app/shaders/d3d11_yuv444_pixel_end.hlsli new file mode 100644 index 00000000..163109ce --- /dev/null +++ b/app/shaders/d3d11_yuv444_pixel_end.hlsli @@ -0,0 +1,13 @@ +min16float4 main(ShaderInput input) : SV_TARGET +{ + // Clamp the texcoords to avoid sampling the row of texels adjacent to the alignment padding + min16float3 yuv = swizzle(videoTex.Sample(theSampler, min(input.tex, chromaTexMax.rg))); + + // Subtract the YUV offset for limited vs full range + yuv -= offsets; + + // Multiply by the conversion matrix for this colorspace + yuv = mul(yuv, cscMatrix); + + return min16float4(yuv, 1.0); +} \ No newline at end of file diff --git a/app/shaders/d3d11_yuv444_pixel_start.hlsli b/app/shaders/d3d11_yuv444_pixel_start.hlsli new file mode 100644 index 00000000..ed9c42af --- /dev/null +++ b/app/shaders/d3d11_yuv444_pixel_start.hlsli @@ -0,0 +1,19 @@ +Texture2D videoTex : register(t0); +SamplerState theSampler : register(s0); + +struct ShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; +}; + +cbuffer ChromaLimitBuf : register(b0) +{ + min16float3 chromaTexMax; +}; + +cbuffer CSC_CONST_BUF : register(b1) +{ + min16float3x3 cscMatrix; + min16float3 offsets; +}; \ No newline at end of file diff --git a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp index f49fe389..7388f8eb 100644 --- a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp +++ b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp @@ -13,6 +13,9 @@ #include +// Custom decoder GUID for Intel HEVC 444 +DEFINE_GUID(D3D11_DECODER_PROFILE_HEVC_VLD_Main444_10_Intel,0x6a6a81ba,0x912a,0x485d,0xb5,0x7f,0xcc,0xd2,0xd3,0x7b,0x8d,0x94); + #define SAFE_COM_RELEASE(x) if (x) { (x)->Release(); } typedef struct _VERTEX @@ -73,6 +76,15 @@ typedef struct _CSC_CONST_BUF } 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 k_VideoShaderNames = +{ + "d3d11_genyuv_pixel.fxc", + "d3d11_bt601lim_pixel.fxc", + "d3d11_bt2020lim_pixel.fxc", + "d3d11_ayuv_pixel.fxc", + "d3d11_y410_pixel.fxc", +}; + D3D11VARenderer::D3D11VARenderer(int decoderSelectionPass) : m_DecoderSelectionPass(decoderSelectionPass), m_DevicesWithFL11Support(0), @@ -86,9 +98,6 @@ D3D11VARenderer::D3D11VARenderer(int decoderSelectionPass) m_LastFullRange(false), m_LastColorTrc(AVCOL_TRC_UNSPECIFIED), m_AllowTearing(false), - m_VideoGenericPixelShader(nullptr), - m_VideoBt601LimPixelShader(nullptr), - m_VideoBt2020LimPixelShader(nullptr), m_VideoVertexBuffer(nullptr), m_VideoTexture(nullptr), m_OverlayLock(0), @@ -113,9 +122,9 @@ D3D11VARenderer::~D3D11VARenderer() SDL_DestroyMutex(m_ContextLock); SAFE_COM_RELEASE(m_VideoVertexBuffer); - SAFE_COM_RELEASE(m_VideoBt2020LimPixelShader); - SAFE_COM_RELEASE(m_VideoBt601LimPixelShader); - SAFE_COM_RELEASE(m_VideoGenericPixelShader); + for (auto shader : m_VideoPixelShaders) { + SAFE_COM_RELEASE(shader); + } for (int i = 0; i < ARRAYSIZE(m_VideoTextureResourceViews); i++) { SAFE_COM_RELEASE(m_VideoTextureResourceViews[i][0]); @@ -289,11 +298,6 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) "D3D11VA renderer is only supported on Windows 10 or later."); return false; } - else if (params->videoFormat & VIDEO_FORMAT_MASK_YUV444) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "D3D11VA renderer does not support YUV444 (TODO!)"); - return false; - } if (!SDL_DXGIGetOutputInfo(SDL_GetWindowDisplayIndex(params->window), &adapterIndex, &outputIndex)) { @@ -502,10 +506,15 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) AVHWFramesContext* framesContext = (AVHWFramesContext*)m_HwFramesContext->data; - // We require NV12 or P010 textures for our shader framesContext->format = AV_PIX_FMT_D3D11; - framesContext->sw_format = (params->videoFormat & VIDEO_FORMAT_MASK_10BIT) ? - AV_PIX_FMT_P010 : AV_PIX_FMT_NV12; + if (params->videoFormat & VIDEO_FORMAT_MASK_10BIT) { + framesContext->sw_format = (params->videoFormat & VIDEO_FORMAT_MASK_YUV444) ? + AV_PIX_FMT_XV30 : AV_PIX_FMT_P010; + } + else { + framesContext->sw_format = (params->videoFormat & VIDEO_FORMAT_MASK_YUV444) ? + AV_PIX_FMT_VUYX : AV_PIX_FMT_NV12; + } framesContext->width = FFALIGN(params->width, m_TextureAlignment); framesContext->height = FFALIGN(params->height, m_TextureAlignment); @@ -529,6 +538,10 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) return false; } + D3D11_TEXTURE2D_DESC textureDesc; + d3d11vaFramesContext->texture_infos->texture->GetDesc(&textureDesc); + m_TextureFormat = textureDesc.Format; + if (m_BindDecoderOutputTextures) { // Create SRVs for all textures in the decoder pool if (!setupTexturePoolViews(d3d11vaFramesContext)) { @@ -696,27 +709,46 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame) { bool fullRange = isFrameFullRange(frame); int colorspace = getFrameColorspace(frame); + bool yuv444 = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_YUV444); - // We have purpose-built shaders for the common Rec 601 (SDR) and Rec 2020 (HDR) cases - if (!fullRange && colorspace == COLORSPACE_REC_601) { - m_DeviceContext->PSSetShader(m_VideoBt601LimPixelShader, nullptr, 0); + // 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], nullptr, 0); } - else if (!fullRange && colorspace == COLORSPACE_REC_2020) { - m_DeviceContext->PSSetShader(m_VideoBt2020LimPixelShader, nullptr, 0); + else if (!yuv444 && !fullRange && colorspace == COLORSPACE_REC_2020) { + m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::BT_2020_LIMITED_YUV_420], nullptr, 0); } else { - // We'll need to use the generic shader for this colorspace and color range combo - m_DeviceContext->PSSetShader(m_VideoGenericPixelShader, nullptr, 0); + if (yuv444) { + // We'll need to use one of the 4:4:4 shaders for this pixel format + switch (m_TextureFormat) + { + case DXGI_FORMAT_AYUV: + m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::GENERIC_AYUV], nullptr, 0); + break; + case DXGI_FORMAT_Y410: + m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::GENERIC_Y410], nullptr, 0); + break; + default: + SDL_assert(false); + } + } + else { + // We'll need to use the generic 4:2:0 shader for this colorspace and color range combo + m_DeviceContext->PSSetShader(m_VideoPixelShaders[PixelShaders::GENERIC_YUV_420], nullptr, 0); + } // If nothing has changed since last frame, we're done if (colorspace == m_LastColorSpace && fullRange == m_LastFullRange) { return; } - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "Falling back to generic video pixel shader for %d (%s range)", - colorspace, - fullRange ? "full" : "limited"); + 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); @@ -967,6 +999,15 @@ bool D3D11VARenderer::checkDecoderSupport(IDXGIAdapter* adapter) HRESULT hr; ID3D11VideoDevice* videoDevice; + DXGI_ADAPTER_DESC adapterDesc; + hr = adapter->GetDesc(&adapterDesc); + if (FAILED(hr)) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "IDXGIAdapter::GetDesc() failed: %x", + hr); + return false; + } + // Derive a ID3D11VideoDevice from our ID3D11Device. hr = m_Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&videoDevice); if (FAILED(hr)) { @@ -1055,6 +1096,46 @@ bool D3D11VARenderer::checkDecoderSupport(IDXGIAdapter* adapter) } break; + case VIDEO_FORMAT_H265_REXT8_444: + if (adapterDesc.VendorId != 0x8086) { + // This custom D3D11VA profile is only supported on Intel GPUs + videoDevice->Release(); + return false; + } + else if (FAILED(videoDevice->CheckVideoDecoderFormat(&D3D11_DECODER_PROFILE_HEVC_VLD_Main444_10_Intel, DXGI_FORMAT_AYUV, &supported))) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "GPU doesn't support HEVC Main 444 8-bit decoding"); + videoDevice->Release(); + return false; + } + else if (!supported) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "GPU doesn't support HEVC Main 444 8-bit decoding to AYUV format"); + videoDevice->Release(); + return false; + } + break; + + case VIDEO_FORMAT_H265_REXT10_444: + if (adapterDesc.VendorId != 0x8086) { + // This custom D3D11VA profile is only supported on Intel GPUs + videoDevice->Release(); + return false; + } + else if (FAILED(videoDevice->CheckVideoDecoderFormat(&D3D11_DECODER_PROFILE_HEVC_VLD_Main444_10_Intel, DXGI_FORMAT_Y410, &supported))) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "GPU doesn't support HEVC Main 444 10-bit decoding"); + videoDevice->Release(); + return false; + } + else if (!supported) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "GPU doesn't support HEVC Main 444 10-bit decoding to Y410 format"); + videoDevice->Release(); + return false; + } + break; + default: SDL_assert(false); videoDevice->Release(); @@ -1063,15 +1144,6 @@ bool D3D11VARenderer::checkDecoderSupport(IDXGIAdapter* adapter) videoDevice->Release(); - DXGI_ADAPTER_DESC adapterDesc; - hr = adapter->GetDesc(&adapterDesc); - if (FAILED(hr)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "IDXGIAdapter::GetDesc() failed: %x", - hr); - return false; - } - if (DXUtil::isFormatHybridDecodedByHardware(m_DecoderParams.videoFormat, adapterDesc.VendorId, adapterDesc.DeviceId)) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "GPU decoding for format %x is blocked due to hardware limitations", @@ -1206,34 +1278,11 @@ bool D3D11VARenderer::setupRenderingResources() } } + for (int i = 0; i < PixelShaders::_COUNT; i++) { - QByteArray videoPixelShaderBytecode = Path::readDataFile("d3d11_genyuv_pixel.fxc"); + QByteArray videoPixelShaderBytecode = Path::readDataFile(k_VideoShaderNames[i]); - hr = m_Device->CreatePixelShader(videoPixelShaderBytecode.constData(), videoPixelShaderBytecode.length(), nullptr, &m_VideoGenericPixelShader); - if (FAILED(hr)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreatePixelShader() failed: %x", - hr); - return false; - } - } - - { - QByteArray videoPixelShaderBytecode = Path::readDataFile("d3d11_bt601lim_pixel.fxc"); - - hr = m_Device->CreatePixelShader(videoPixelShaderBytecode.constData(), videoPixelShaderBytecode.length(), nullptr, &m_VideoBt601LimPixelShader); - if (FAILED(hr)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreatePixelShader() failed: %x", - hr); - return false; - } - } - - { - QByteArray videoPixelShaderBytecode = Path::readDataFile("d3d11_bt2020lim_pixel.fxc"); - - hr = m_Device->CreatePixelShader(videoPixelShaderBytecode.constData(), videoPixelShaderBytecode.length(), nullptr, &m_VideoBt2020LimPixelShader); + hr = m_Device->CreatePixelShader(videoPixelShaderBytecode.constData(), videoPixelShaderBytecode.length(), nullptr, &m_VideoPixelShaders[i]); if (FAILED(hr)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ID3D11Device::CreatePixelShader() failed: %x", @@ -1446,6 +1495,21 @@ bool D3D11VARenderer::setupRenderingResources() return true; } +std::vector D3D11VARenderer::getVideoTextureSRVFormats() +{ + if (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_YUV444) { + // YUV 4:4:4 formats don't use a second SRV + return { (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? + DXGI_FORMAT_R10G10B10A2_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM }; + } + else if (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) { + return { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM }; + } + else { + return { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM }; + } +} + bool D3D11VARenderer::setupVideoTexture() { SDL_assert(!m_BindDecoderOutputTextures); @@ -1457,7 +1521,7 @@ bool D3D11VARenderer::setupVideoTexture() texDesc.Height = m_DecoderParams.height; texDesc.MipLevels = 1; texDesc.ArraySize = 1; - texDesc.Format = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? DXGI_FORMAT_P010 : DXGI_FORMAT_NV12; + texDesc.Format = m_TextureFormat; texDesc.SampleDesc.Quality = 0; texDesc.SampleDesc.Count = 1; texDesc.Usage = D3D11_USAGE_DEFAULT; @@ -1474,29 +1538,26 @@ bool D3D11VARenderer::setupVideoTexture() return false; } - // Create luminance and chrominance SRVs for each plane of the texture + // Create SRVs for the texture D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; - srvDesc.Format = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM; - hr = m_Device->CreateShaderResourceView(m_VideoTexture, &srvDesc, &m_VideoTextureResourceViews[0][0]); - if (FAILED(hr)) { - m_VideoTextureResourceViews[0][0] = nullptr; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreateShaderResourceView() failed: %x", - hr); - return false; - } + int srvIndex = 0; + for (DXGI_FORMAT srvFormat : getVideoTextureSRVFormats()) { + SDL_assert(srvIndex < 2); - srvDesc.Format = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM; - hr = m_Device->CreateShaderResourceView(m_VideoTexture, &srvDesc, &m_VideoTextureResourceViews[0][1]); - if (FAILED(hr)) { - m_VideoTextureResourceViews[0][1] = nullptr; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreateShaderResourceView() failed: %x", - hr); - return false; + srvDesc.Format = srvFormat; + hr = m_Device->CreateShaderResourceView(m_VideoTexture, &srvDesc, &m_VideoTextureResourceViews[0][srvIndex]); + if (FAILED(hr)) { + m_VideoTextureResourceViews[0][srvIndex] = nullptr; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "ID3D11Device::CreateShaderResourceView() failed: %x", + hr); + return false; + } + + srvIndex++; } return true; @@ -1521,24 +1582,23 @@ bool D3D11VARenderer::setupTexturePoolViews(AVD3D11VAFramesContext* frameContext srvDesc.Texture2DArray.FirstArraySlice = frameContext->texture_infos[i].index; - srvDesc.Format = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM; - hr = m_Device->CreateShaderResourceView(frameContext->texture_infos[i].texture, &srvDesc, &m_VideoTextureResourceViews[i][0]); - if (FAILED(hr)) { - m_VideoTextureResourceViews[i][0] = nullptr; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreateShaderResourceView() failed: %x", - hr); - return false; - } + int srvIndex = 0; + for (DXGI_FORMAT srvFormat : getVideoTextureSRVFormats()) { + SDL_assert(srvIndex < 2); - srvDesc.Format = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM; - hr = m_Device->CreateShaderResourceView(frameContext->texture_infos[i].texture, &srvDesc, &m_VideoTextureResourceViews[i][1]); - if (FAILED(hr)) { - m_VideoTextureResourceViews[i][1] = nullptr; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "ID3D11Device::CreateShaderResourceView() failed: %x", - hr); - return false; + srvDesc.Format = srvFormat; + hr = m_Device->CreateShaderResourceView(frameContext->texture_infos[i].texture, + &srvDesc, + &m_VideoTextureResourceViews[i][srvIndex]); + if (FAILED(hr)) { + m_VideoTextureResourceViews[i][srvIndex] = nullptr; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "ID3D11Device::CreateShaderResourceView() failed: %x", + hr); + return false; + } + + srvIndex++; } } diff --git a/app/streaming/video/ffmpeg-renderers/d3d11va.h b/app/streaming/video/ffmpeg-renderers/d3d11va.h index b2a5f4a3..156b1694 100644 --- a/app/streaming/video/ffmpeg-renderers/d3d11va.h +++ b/app/streaming/video/ffmpeg-renderers/d3d11va.h @@ -24,11 +24,21 @@ public: virtual bool needsTestFrame() override; virtual InitFailureReason getInitFailureReason() override; + enum PixelShaders { + GENERIC_YUV_420, + BT_601_LIMITED_YUV_420, + BT_2020_LIMITED_YUV_420, + GENERIC_AYUV, + GENERIC_Y410, + _COUNT + }; + private: static void lockContext(void* lock_ctx); static void unlockContext(void* lock_ctx); bool setupRenderingResources(); + std::vector getVideoTextureSRVFormats(); bool setupVideoTexture(); // for !m_BindDecoderOutputTextures bool setupTexturePoolViews(AVD3D11VAFramesContext* frameContext); // for m_BindDecoderOutputTextures void renderOverlay(Overlay::OverlayType type); @@ -51,6 +61,7 @@ private: DECODER_PARAMETERS m_DecoderParams; int m_TextureAlignment; + DXGI_FORMAT m_TextureFormat; int m_DisplayWidth; int m_DisplayHeight; int m_LastColorSpace; @@ -59,9 +70,7 @@ private: bool m_AllowTearing; - ID3D11PixelShader* m_VideoGenericPixelShader; - ID3D11PixelShader* m_VideoBt601LimPixelShader; - ID3D11PixelShader* m_VideoBt2020LimPixelShader; + std::array m_VideoPixelShaders; ID3D11Buffer* m_VideoVertexBuffer; // Only valid if !m_BindDecoderOutputTextures