diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index bc30f37e5..83481728b 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -476,6 +476,158 @@ namespace dxvk { } + + + D3D11DXGISurface::D3D11DXGISurface( + ID3D11DeviceChild* pContainer, + D3D11CommonTexture* pTexture) + : m_container (pContainer), + m_texture (pTexture) { + + } + + + D3D11DXGISurface::~D3D11DXGISurface() { + + } + + + ULONG STDMETHODCALLTYPE D3D11DXGISurface::AddRef() { + return m_container->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D11DXGISurface::Release() { + return m_container->Release(); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_container->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetPrivateData( + REFGUID Name, + UINT* pDataSize, + void* pData) { + return m_container->GetPrivateData(Name, pDataSize, pData); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::SetPrivateData( + REFGUID Name, + UINT DataSize, + const void* pData) { + return m_container->SetPrivateData(Name, DataSize, pData); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::SetPrivateDataInterface( + REFGUID Name, + const IUnknown* pUnknown) { + return m_container->SetPrivateDataInterface(Name, pUnknown); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetParent( + REFIID riid, + void** ppParent) { + return GetDevice(riid, ppParent); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDevice( + REFIID riid, + void** ppDevice) { + Com device; + m_container->GetDevice(&device); + return device->QueryInterface(riid, ppDevice); + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDesc( + DXGI_SURFACE_DESC* pDesc) { + if (!pDesc) + return DXGI_ERROR_INVALID_CALL; + + auto desc = m_texture->Desc(); + pDesc->Width = desc->Width; + pDesc->Height = desc->Height; + pDesc->Format = desc->Format; + pDesc->SampleDesc = desc->SampleDesc; + return S_OK; + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::Map( + DXGI_MAPPED_RECT* pLockedRect, + UINT MapFlags) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DXGISurface::Map: Stub"); + + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::Unmap() { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DXGISurface::Unmap: Stub"); + + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDC( + BOOL Discard, + HDC* phdc) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DXGISurface::GetDC: Stub"); + + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::ReleaseDC( + RECT* pDirtyRect) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DXGISurface::ReleaseDC: Stub"); + + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetResource( + REFIID riid, + void** ppParentResource, + UINT* pSubresourceIndex) { + HRESULT hr = m_container->QueryInterface(riid, ppParentResource); + if (pSubresourceIndex) + *pSubresourceIndex = 0; + return hr; + } + + + bool D3D11DXGISurface::isSurfaceCompatible() const { + auto desc = m_texture->Desc(); + + return desc->ArraySize == 1 + && desc->MipLevels == 1; + } + + + + D3D11VkInteropSurface::D3D11VkInteropSurface( ID3D11DeviceChild* pContainer, D3D11CommonTexture* pTexture) @@ -646,6 +798,7 @@ namespace dxvk { const D3D11_COMMON_TEXTURE_DESC* pDesc) : m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D), m_interop (this, &m_texture), + m_surface (this, &m_texture), m_d3d10 (this, pDevice->GetD3D10Interface()) { } @@ -676,6 +829,14 @@ namespace dxvk { *ppvObject = ref(&m_d3d10); return S_OK; } + + if (m_surface.isSurfaceCompatible() + && (riid == __uuidof(IDXGISurface) + || riid == __uuidof(IDXGISurface1) + || riid == __uuidof(IDXGISurface2))) { + *ppvObject = ref(&m_surface); + return S_OK; + } if (riid == __uuidof(IDXGIVkInteropSurface)) { *ppvObject = ref(&m_interop); diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 5e291da7f..acc0d008c 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -226,6 +226,83 @@ namespace dxvk { VkImageUsageFlags Usage); }; + + + /** + * \brief IDXGISurface implementation for D3D11 textures + * + * Provides an implementation for 2D textures that + * have only one array layer and one mip level. + */ + class D3D11DXGISurface : public IDXGISurface2 { + + public: + + D3D11DXGISurface( + ID3D11DeviceChild* pContainer, + D3D11CommonTexture* pTexture); + + ~D3D11DXGISurface(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetPrivateData( + REFGUID Name, + UINT* pDataSize, + void* pData); + + HRESULT STDMETHODCALLTYPE SetPrivateData( + REFGUID Name, + UINT DataSize, + const void* pData); + + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + REFGUID Name, + const IUnknown* pUnknown); + + HRESULT STDMETHODCALLTYPE GetParent( + REFIID riid, + void** ppParent); + + HRESULT STDMETHODCALLTYPE GetDevice( + REFIID riid, + void** ppDevice); + + HRESULT STDMETHODCALLTYPE GetDesc( + DXGI_SURFACE_DESC* pDesc); + + HRESULT STDMETHODCALLTYPE Map( + DXGI_MAPPED_RECT* pLockedRect, + UINT MapFlags); + + HRESULT STDMETHODCALLTYPE Unmap(); + + HRESULT STDMETHODCALLTYPE GetDC( + BOOL Discard, + HDC* phdc); + + HRESULT STDMETHODCALLTYPE ReleaseDC( + RECT* pDirtyRect); + + HRESULT STDMETHODCALLTYPE GetResource( + REFIID riid, + void** ppParentResource, + UINT* pSubresourceIndex); + + bool isSurfaceCompatible() const; + + private: + + ID3D11DeviceChild* m_container; + D3D11CommonTexture* m_texture; + + }; /** @@ -355,6 +432,7 @@ namespace dxvk { D3D11CommonTexture m_texture; D3D11VkInteropSurface m_interop; + D3D11DXGISurface m_surface; D3D10Texture2D m_d3d10; };