#include "d3d11_buffer.h" #include "d3d11_texture.h" #include "d3d11_resource.h" #include "../util/util_shared_res.h" namespace dxvk { D3D11DXGIResource::D3D11DXGIResource( ID3D11Resource* pResource) : m_resource(pResource) { } D3D11DXGIResource::~D3D11DXGIResource() { } ULONG STDMETHODCALLTYPE D3D11DXGIResource::AddRef() { return m_resource->AddRef(); } ULONG STDMETHODCALLTYPE D3D11DXGIResource::Release() { return m_resource->Release(); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::QueryInterface( REFIID riid, void** ppvObject) { return m_resource->QueryInterface(riid, ppvObject); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetPrivateData( REFGUID Name, UINT* pDataSize, void* pData) { return m_resource->GetPrivateData(Name, pDataSize, pData); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::SetPrivateData( REFGUID Name, UINT DataSize, const void* pData) { return m_resource->SetPrivateData(Name, DataSize, pData); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::SetPrivateDataInterface( REFGUID Name, const IUnknown* pUnknown) { return m_resource->SetPrivateDataInterface(Name, pUnknown); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetParent( REFIID riid, void** ppParent) { return GetDevice(riid, ppParent); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetDevice( REFIID riid, void** ppDevice) { Com device; m_resource->GetDevice(&device); return device->QueryInterface(riid, ppDevice); } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetEvictionPriority( UINT* pEvictionPriority) { *pEvictionPriority = m_resource->GetEvictionPriority(); return S_OK; } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetSharedHandle( HANDLE* pSharedHandle) { auto texture = GetCommonTexture(m_resource); if (texture == nullptr || pSharedHandle == nullptr || !(texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED)) return E_INVALIDARG; HANDLE kmtHandle = texture->GetImage()->sharedHandle(); if (kmtHandle == INVALID_HANDLE_VALUE) return E_INVALIDARG; *pSharedHandle = kmtHandle; return S_OK; } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetUsage( DXGI_USAGE* pUsage) { D3D11_COMMON_RESOURCE_DESC desc; HRESULT hr = GetCommonResourceDesc(m_resource, &desc); if (FAILED(hr)) return hr; DXGI_USAGE usage = desc.DxgiUsage; switch (desc.Usage) { case D3D11_USAGE_IMMUTABLE: usage |= DXGI_CPU_ACCESS_NONE; break; case D3D11_USAGE_DEFAULT: usage |= DXGI_CPU_ACCESS_NONE; break; case D3D11_USAGE_DYNAMIC: usage |= DXGI_CPU_ACCESS_DYNAMIC; break; case D3D11_USAGE_STAGING: usage |= DXGI_CPU_ACCESS_READ_WRITE; break; } // TODO add flags for swap chain back buffers if (desc.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_CONSTANT_BUFFER)) usage |= DXGI_USAGE_SHADER_INPUT; if (desc.BindFlags & D3D11_BIND_RENDER_TARGET) usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; if (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) usage |= DXGI_USAGE_UNORDERED_ACCESS; *pUsage = usage; return S_OK; } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::SetEvictionPriority( UINT EvictionPriority) { m_resource->SetEvictionPriority(EvictionPriority); return S_OK; } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::CreateSharedHandle( const SECURITY_ATTRIBUTES* pAttributes, DWORD dwAccess, LPCWSTR lpName, HANDLE* pHandle) { auto texture = GetCommonTexture(m_resource); if (texture == nullptr || pHandle == nullptr || !(texture->Desc()->MiscFlags & (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE))) return E_INVALIDARG; if (lpName) Logger::warn("Naming shared resources not supported"); HANDLE handle = texture->GetImage()->sharedHandle(); if (handle == INVALID_HANDLE_VALUE) return E_INVALIDARG; if (texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED) handle = openKmtHandle( handle ); *pHandle = handle; return S_OK; } HRESULT STDMETHODCALLTYPE D3D11DXGIResource::CreateSubresourceSurface( UINT index, IDXGISurface2** ppSurface) { InitReturnPtr(ppSurface); Logger::err("D3D11DXGIResource::CreateSubresourceSurface: Stub"); return E_NOTIMPL; } HRESULT GetResource11on12Info( ID3D11Resource* pResource, D3D11_ON_12_RESOURCE_INFO* p11on12Info) { auto buffer = GetCommonBuffer (pResource); auto texture = GetCommonTexture(pResource); if (buffer != nullptr) *p11on12Info = buffer->Get11on12Info(); else if (texture != nullptr) *p11on12Info = texture->Get11on12Info(); else return E_INVALIDARG; if (p11on12Info->Resource == nullptr) return E_INVALIDARG; return S_OK; } HRESULT GetCommonResourceDesc( ID3D11Resource* pResource, D3D11_COMMON_RESOURCE_DESC* pDesc) { auto buffer = GetCommonBuffer (pResource); auto texture = GetCommonTexture(pResource); if (buffer != nullptr) { pDesc->Dim = D3D11_RESOURCE_DIMENSION_BUFFER; pDesc->Format = DXGI_FORMAT_UNKNOWN; pDesc->Usage = buffer->Desc()->Usage; pDesc->BindFlags = buffer->Desc()->BindFlags; pDesc->CPUAccessFlags = buffer->Desc()->CPUAccessFlags; pDesc->MiscFlags = buffer->Desc()->MiscFlags; pDesc->DxgiUsage = 0; return S_OK; } else if (texture != nullptr) { pResource->GetType(&pDesc->Dim); pDesc->Format = texture->Desc()->Format; pDesc->Usage = texture->Desc()->Usage; pDesc->BindFlags = texture->Desc()->BindFlags; pDesc->CPUAccessFlags = texture->Desc()->CPUAccessFlags; pDesc->MiscFlags = texture->Desc()->MiscFlags; pDesc->DxgiUsage = texture->GetDxgiUsage(); return S_OK; } else { pDesc->Dim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pDesc->Format = DXGI_FORMAT_UNKNOWN; pDesc->Usage = D3D11_USAGE_DEFAULT; pDesc->BindFlags = 0; pDesc->CPUAccessFlags = 0; pDesc->MiscFlags = 0; pDesc->DxgiUsage = 0; return E_INVALIDARG; } } Rc GetPagedResource( ID3D11Resource* pResource) { auto texture = GetCommonTexture(pResource); if (texture) return texture->GetImage(); return static_cast(pResource)->GetBuffer(); } BOOL CheckResourceViewCompatibility( ID3D11Resource* pResource, UINT BindFlags, DXGI_FORMAT Format, UINT Plane) { auto texture = GetCommonTexture(pResource); auto buffer = GetCommonBuffer (pResource); return texture != nullptr ? texture->CheckViewCompatibility(BindFlags, Format, Plane) : buffer ->CheckViewCompatibility(BindFlags, Format); } HRESULT ResourceAddRefPrivate(ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION Type) { switch (Type) { case D3D11_RESOURCE_DIMENSION_BUFFER: static_cast (pResource)->AddRefPrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE1D: static_cast(pResource)->AddRefPrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: static_cast(pResource)->AddRefPrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: static_cast(pResource)->AddRefPrivate(); return S_OK; default: return E_INVALIDARG; } } HRESULT ResourceAddRefPrivate(ID3D11Resource* pResource) { D3D11_RESOURCE_DIMENSION dim; pResource->GetType(&dim); return ResourceAddRefPrivate(pResource, dim); } HRESULT ResourceReleasePrivate(ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION Type) { switch (Type) { case D3D11_RESOURCE_DIMENSION_BUFFER: static_cast (pResource)->ReleasePrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE1D: static_cast(pResource)->ReleasePrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: static_cast(pResource)->ReleasePrivate(); return S_OK; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: static_cast(pResource)->ReleasePrivate(); return S_OK; default: return E_INVALIDARG; } } HRESULT ResourceReleasePrivate(ID3D11Resource* pResource) { D3D11_RESOURCE_DIMENSION dim; pResource->GetType(&dim); return ResourceReleasePrivate(pResource, dim); } }