From 1df26a360533967235dd143e15e0e7685211b11e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 6 May 2021 15:46:44 +0200 Subject: [PATCH] [d3d11] Implement video processor views --- src/d3d11/d3d11_device.cpp | 18 +++- src/d3d11/d3d11_video.cpp | 175 +++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_video.h | 69 +++++++++++++++ 3 files changed, 258 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 2f8a62b5..64babff2 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2479,8 +2479,13 @@ namespace dxvk { ID3D11VideoProcessorEnumerator* pEnum, const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc, ID3D11VideoProcessorInputView** ppVPIView) { - Logger::err("D3D11VideoDevice::CreateVideoProcessorInputView: Stub"); - return E_NOTIMPL; + try { + *ppVPIView = ref(new D3D11VideoProcessorInputView(m_device, pResource, *pDesc)); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } @@ -2489,8 +2494,13 @@ namespace dxvk { ID3D11VideoProcessorEnumerator* pEnum, const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC* pDesc, ID3D11VideoProcessorOutputView** ppVPOView) { - Logger::err("D3D11VideoDevice::CreateVideoProcessorOutputView: Stub"); - return E_NOTIMPL; + try { + *ppVPOView = ref(new D3D11VideoProcessorOutputView(m_device, pResource, *pDesc)); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index afd5aaa8..d9f4084d 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1,4 +1,7 @@ +#include + #include "d3d11_context.h" +#include "d3d11_context_imm.h" #include "d3d11_video.h" namespace dxvk { @@ -124,4 +127,176 @@ namespace dxvk { m_enumerator->GetVideoProcessorRateConversionCaps(m_rateConversionIndex, pCaps); } + + + + D3D11VideoProcessorInputView::D3D11VideoProcessorInputView( + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC& Desc) + : D3D11DeviceChild(pDevice), + m_resource(pResource), m_desc(Desc) { + D3D11_COMMON_RESOURCE_DESC resourceDesc = { }; + GetCommonResourceDesc(pResource, &resourceDesc); + + DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat(resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); + DXGI_VK_FORMAT_FAMILY formatFamily = pDevice->LookupFamily(resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); + + VkImageAspectFlags aspectMask = imageFormatInfo(formatInfo.Format)->aspectMask; + + DxvkImageViewCreateInfo viewInfo; + viewInfo.format = formatInfo.Format; + viewInfo.swizzle = formatInfo.Swizzle; + viewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + switch (m_desc.ViewDimension) { + case D3D11_VPIV_DIMENSION_TEXTURE2D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.minLevel = m_desc.Texture2D.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + throw DxvkError("Invalid view dimension"); + } + + for (uint32_t i = 0; aspectMask && i < m_views.size(); i++) { + viewInfo.aspect = vk::getNextAspect(aspectMask); + + if (viewInfo.aspect != VK_IMAGE_ASPECT_COLOR_BIT) + viewInfo.format = formatFamily.Formats[i]; + + m_views[i] = pDevice->GetDXVKDevice()->createImageView( + GetCommonTexture(pResource)->GetImage(), viewInfo); + } + + m_isYCbCr = IsYCbCrFormat(resourceDesc.Format); + } + + + D3D11VideoProcessorInputView::~D3D11VideoProcessorInputView() { + + } + + + bool D3D11VideoProcessorInputView::IsYCbCrFormat(DXGI_FORMAT Format) { + static const std::array s_formats = {{ + DXGI_FORMAT_NV12, + DXGI_FORMAT_YUY2, + DXGI_FORMAT_AYUV, + }}; + + return std::find(s_formats.begin(), s_formats.end(), Format) != s_formats.end(); + } + + + HRESULT STDMETHODCALLTYPE D3D11VideoProcessorInputView::QueryInterface( + REFIID riid, + void** ppvObject) { + if (riid == __uuidof(IUnknown) + || riid == __uuidof(ID3D11DeviceChild) + || riid == __uuidof(ID3D11View) + || riid == __uuidof(ID3D11VideoProcessorInputView)) { + *ppvObject = ref(this); + return S_OK; + } + + Logger::warn("D3D11VideoProcessorInputView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + void STDMETHODCALLTYPE D3D11VideoProcessorInputView::GetResource( + ID3D11Resource** ppResource) { + *ppResource = m_resource.ref(); + } + + + void STDMETHODCALLTYPE D3D11VideoProcessorInputView::GetDesc( + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc) { + *pDesc = m_desc; + } + + + + D3D11VideoProcessorOutputView::D3D11VideoProcessorOutputView( + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC& Desc) + : D3D11DeviceChild(pDevice), + m_resource(pResource), m_desc(Desc) { + D3D11_COMMON_RESOURCE_DESC resourceDesc = { }; + GetCommonResourceDesc(pResource, &resourceDesc); + + DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat( + resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); + + DxvkImageViewCreateInfo viewInfo; + viewInfo.format = formatInfo.Format; + viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.swizzle = formatInfo.Swizzle; + viewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + + switch (m_desc.ViewDimension) { + case D3D11_VPOV_DIMENSION_TEXTURE2D: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.minLevel = m_desc.Texture2D.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = 0; + viewInfo.numLayers = 1; + break; + + case D3D11_VPOV_DIMENSION_TEXTURE2DARRAY: + viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + viewInfo.minLevel = m_desc.Texture2DArray.MipSlice; + viewInfo.numLevels = 1; + viewInfo.minLayer = m_desc.Texture2DArray.FirstArraySlice; + viewInfo.numLayers = m_desc.Texture2DArray.ArraySize; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + throw DxvkError("Invalid view dimension"); + } + + m_view = pDevice->GetDXVKDevice()->createImageView( + GetCommonTexture(pResource)->GetImage(), viewInfo); + } + + + D3D11VideoProcessorOutputView::~D3D11VideoProcessorOutputView() { + + } + + + HRESULT STDMETHODCALLTYPE D3D11VideoProcessorOutputView::QueryInterface( + REFIID riid, + void** ppvObject) { + if (riid == __uuidof(IUnknown) + || riid == __uuidof(ID3D11DeviceChild) + || riid == __uuidof(ID3D11View) + || riid == __uuidof(ID3D11VideoProcessorOutputView)) { + *ppvObject = ref(this); + return S_OK; + } + + Logger::warn("D3D11VideoProcessorOutputView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + void STDMETHODCALLTYPE D3D11VideoProcessorOutputView::GetResource( + ID3D11Resource** ppResource) { + *ppResource = m_resource.ref(); + } + + + void STDMETHODCALLTYPE D3D11VideoProcessorOutputView::GetDesc( + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC* pDesc) { + *pDesc = m_desc; + } + } diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index e4f96d91..6eba66f3 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -77,4 +77,73 @@ namespace dxvk { }; + + + class D3D11VideoProcessorInputView : public D3D11DeviceChild { + + public: + + D3D11VideoProcessorInputView( + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC& Desc); + + ~D3D11VideoProcessorInputView(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetResource( + ID3D11Resource** ppResource); + + void STDMETHODCALLTYPE GetDesc( + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc); + + const bool IsYCbCr() const { + return m_isYCbCr; + } + + private: + + Com m_resource; + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC m_desc; + std::array, 2> m_views; + bool m_isYCbCr = false; + + static bool IsYCbCrFormat(DXGI_FORMAT Format); + + }; + + + + class D3D11VideoProcessorOutputView : public D3D11DeviceChild { + + public: + + D3D11VideoProcessorOutputView( + D3D11Device* pDevice, + ID3D11Resource* pResource, + const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC& Desc); + + ~D3D11VideoProcessorOutputView(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetResource( + ID3D11Resource** ppResource); + + void STDMETHODCALLTYPE GetDesc( + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC* pDesc); + + private: + + Com m_resource; + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC m_desc; + Rc m_view; + + }; + }