diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index e9e9f1b3..08b68544 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -2,13 +2,14 @@ #include -#include "d3d11_resource.h" +#include "d3d11_device_child.h" namespace dxvk { class D3D11Device; - class D3D11Buffer : public D3D11Resource { + + class D3D11Buffer : public D3D11DeviceChild { public: diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index bd58c7b2..ab9df7be 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -8,7 +8,9 @@ namespace dxvk { Rc device) : m_parent(parent), m_device(device) { - + m_context = m_device->createContext(); + m_cmdList = m_device->createCommandList(); + m_context->beginRecording(m_cmdList); } @@ -35,12 +37,12 @@ namespace dxvk { D3D11_DEVICE_CONTEXT_TYPE D3D11DeviceContext::GetType() { - return D3D11_DEVICE_CONTEXT_IMMEDIATE; + return m_type; } UINT D3D11DeviceContext::GetContextFlags() { - return 0; + return m_flags; } @@ -50,7 +52,16 @@ namespace dxvk { void D3D11DeviceContext::Flush() { - Logger::err("D3D11DeviceContext::Flush: Not implemented"); + if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) { + m_context->endRecording(); + m_device->submitCommandList( + m_cmdList, nullptr, nullptr); + + m_cmdList = m_device->createCommandList(); + m_context->beginRecording(m_cmdList); + } else { + Logger::err("D3D11DeviceContext::Flush: Not supported on deferred context"); + } } @@ -64,8 +75,13 @@ namespace dxvk { HRESULT D3D11DeviceContext::FinishCommandList( WINBOOL RestoreDeferredContextState, ID3D11CommandList **ppCommandList) { - Logger::err("D3D11DeviceContext::FinishCommandList: Not implemented"); - return E_NOTIMPL; + if (m_type == D3D11_DEVICE_CONTEXT_DEFERRED) { + Logger::err("D3D11DeviceContext::FinishCommandList: Not implemented"); + return E_NOTIMPL; + } else { + Logger::err("D3D11DeviceContext::FinishCommandList: Not supported on immediate context"); + return DXGI_ERROR_INVALID_CALL; + } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 7d8f7b14..1c52d5ff 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -539,8 +539,12 @@ namespace dxvk { ID3D11Device* const m_parent; - Rc m_device; - Rc m_context; + const D3D11_DEVICE_CONTEXT_TYPE m_type = D3D11_DEVICE_CONTEXT_IMMEDIATE; + const UINT m_flags = 0; + + Rc m_device; + Rc m_context; + Rc m_cmdList; }; diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 30ace845..4b6a97a8 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -4,6 +4,7 @@ #include "d3d11_context.h" #include "d3d11_device.h" #include "d3d11_texture.h" +#include "d3d11_view.h" namespace dxvk { @@ -31,8 +32,8 @@ namespace dxvk { COM_QUERY_IFACE(riid, ppvObject, ID3D11Device); COM_QUERY_IFACE(riid, ppvObject, ID3D11DevicePrivate); - if (riid == __uuidof(IDXGIDevicePrivate) - || riid == __uuidof(IDXGIDevice)) + if (riid == __uuidof(IDXGIDevice) + || riid == __uuidof(IDXGIDevicePrivate)) return m_dxgiDevice->QueryInterface(riid, ppvObject); Logger::warn("D3D11Device::QueryInterface: Unknown interface query"); @@ -98,8 +99,12 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, ID3D11RenderTargetView** ppRTView) { - Logger::err("D3D11Device::CreateRenderTargetView: Not implemented"); - return E_NOTIMPL; + // TODO fill desc + // TODO create view + D3D11_RENDER_TARGET_VIEW_DESC desc; + + *ppRTView = ref(new D3D11RenderTargetView(this, desc)); + return S_OK; } @@ -107,6 +112,17 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, ID3D11DepthStencilView** ppDepthStencilView) { + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&resourceDim); + + // Only 2D textures and 2D texture arrays are allowed + if (resourceDim != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { + Logger::err("D3D11Device::CreateRenderTargetView: Unsupported resource type"); + return E_INVALIDARG; + } + + + Logger::err("D3D11Device::CreateRenderTargetView: Not implemented"); return E_NOTIMPL; } @@ -375,9 +391,9 @@ namespace dxvk { HRESULT D3D11Device::WrapSwapChainBackBuffer( - const Rc& image, - const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IUnknown** ppInterface) { + IDXGIImageResourcePrivate* pResource, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IUnknown** ppInterface) { D3D11_TEXTURE2D_DESC desc; desc.Width = pSwapChainDesc->BufferDesc.Width; desc.Height = pSwapChainDesc->BufferDesc.Height; @@ -391,7 +407,7 @@ namespace dxvk { desc.CPUAccessFlags = 0; desc.MiscFlags = 0; - *ppInterface = ref(new D3D11Texture2D(this, desc, image)); + *ppInterface = ref(new D3D11Texture2D(this, pResource, desc)); return S_OK; } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index eed41459..c9b4360f 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include "d3d11_interfaces.h" @@ -216,9 +216,9 @@ namespace dxvk { UINT GetExceptionMode() final; HRESULT WrapSwapChainBackBuffer( - const Rc& image, - const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IUnknown** ppInterface) final; + IDXGIImageResourcePrivate* pResource, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IUnknown** ppInterface) final; HRESULT FlushRenderingCommands() final; diff --git a/src/d3d11/d3d11_device_child.h b/src/d3d11/d3d11_device_child.h index 5d679828..485b23a6 100644 --- a/src/d3d11/d3d11_device_child.h +++ b/src/d3d11/d3d11_device_child.h @@ -6,8 +6,8 @@ namespace dxvk { - template - class D3D11DeviceChild : public ComObject { + template + class D3D11DeviceChild : public ComObject { public: diff --git a/src/d3d11/d3d11_interfaces.h b/src/d3d11/d3d11_interfaces.h index d49b3be7..9580afcd 100644 --- a/src/d3d11/d3d11_interfaces.h +++ b/src/d3d11/d3d11_interfaces.h @@ -1,9 +1,11 @@ #pragma once -#include "../dxvk/dxvk_device.h" - #include "d3d11_include.h" +#include "../dxgi/dxgi_interfaces.h" + +#include "../dxvk/dxvk_device.h" + /** * \brief Private device interface * @@ -26,7 +28,7 @@ ID3D11DevicePrivate : public ID3D11Device { * \returns \c S_OK on success */ virtual HRESULT WrapSwapChainBackBuffer( - const dxvk::Rc& image, + IDXGIImageResourcePrivate* pResource, const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IUnknown** ppInterface) = 0; @@ -47,4 +49,5 @@ ID3D11DevicePrivate : public ID3D11Device { virtual dxvk::Rc GetDXVKDevice() = 0; }; + DXVK_DEFINE_GUID(ID3D11DevicePrivate); \ No newline at end of file diff --git a/src/d3d11/d3d11_main.cpp b/src/d3d11/d3d11_main.cpp index d16de784..db10640b 100644 --- a/src/d3d11/d3d11_main.cpp +++ b/src/d3d11/d3d11_main.cpp @@ -105,7 +105,7 @@ extern "C" { if (ppDevice != nullptr) { Com dxvkDevice = nullptr; - if (FAILED(DXGICreateDXVKDevice(dxvkAdapter.ptr(), &dxvkDevice))) { + if (FAILED(DXGICreateDevicePrivate(dxvkAdapter.ptr(), &dxvkDevice))) { Logger::err("D3D11CreateDevice: Failed to create DXGI device"); return E_FAIL; } diff --git a/src/d3d11/d3d11_resource.h b/src/d3d11/d3d11_resource.h deleted file mode 100644 index 18405144..00000000 --- a/src/d3d11/d3d11_resource.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "d3d11_device_child.h" - -namespace dxvk { - - template - class D3D11Resource : public D3D11DeviceChild { - - public: - - UINT GetEvictionPriority() final { - return m_evictionPriority; - } - - void SetEvictionPriority(UINT EvictionPriority) final { - m_evictionPriority = EvictionPriority; - } - - private: - - UINT m_evictionPriority = 0; - - }; - -} diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index f3f77509..a588e255 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -4,12 +4,12 @@ namespace dxvk { D3D11Texture2D::D3D11Texture2D( - D3D11Device* device, - const D3D11_TEXTURE2D_DESC& desc, - const Rc& image) - : m_device(device), - m_desc (desc), - m_image (image) { + D3D11Device* device, + IDXGIImageResourcePrivate* resource, + const D3D11_TEXTURE2D_DESC& desc) + : m_device (device), + m_resource(resource), + m_desc (desc) { } @@ -21,10 +21,13 @@ namespace dxvk { HRESULT D3D11Texture2D::QueryInterface(REFIID riid, void** ppvObject) { COM_QUERY_IFACE(riid, ppvObject, IUnknown); - COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource); COM_QUERY_IFACE(riid, ppvObject, ID3D11Texture2D); + if (riid == __uuidof(IDXGIResource) + || riid == __uuidof(IDXGIImageResourcePrivate)) + return m_resource->QueryInterface(riid, ppvObject); + Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query"); return E_NOINTERFACE; } @@ -40,6 +43,18 @@ namespace dxvk { } + UINT D3D11Texture2D::GetEvictionPriority() { + UINT EvictionPriority = DXGI_RESOURCE_PRIORITY_NORMAL; + m_resource->GetEvictionPriority(&EvictionPriority); + return EvictionPriority; + } + + + void D3D11Texture2D::SetEvictionPriority(UINT EvictionPriority) { + m_resource->SetEvictionPriority(EvictionPriority); + } + + void D3D11Texture2D::GetDesc(D3D11_TEXTURE2D_DESC *pDesc) { *pDesc = m_desc; } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 2ae275c1..e323b858 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -2,20 +2,22 @@ #include -#include "d3d11_resource.h" +#include "d3d11_device_child.h" +#include "d3d11_interfaces.h" namespace dxvk { class D3D11Device; - class D3D11Texture2D : public D3D11Resource { + + class D3D11Texture2D : public D3D11DeviceChild { public: D3D11Texture2D( - D3D11Device* device, - const D3D11_TEXTURE2D_DESC& desc, - const Rc& image); + D3D11Device* device, + IDXGIImageResourcePrivate* resource, + const D3D11_TEXTURE2D_DESC& desc); ~D3D11Texture2D(); HRESULT QueryInterface( @@ -28,15 +30,18 @@ namespace dxvk { void GetType( D3D11_RESOURCE_DIMENSION *pResourceDimension) final; + UINT GetEvictionPriority() final; + + void SetEvictionPriority(UINT EvictionPriority) final; + void GetDesc( D3D11_TEXTURE2D_DESC *pDesc) final; private: - Com m_device; - - D3D11_TEXTURE2D_DESC m_desc; - Rc m_image; + Com m_device; + Com m_resource; + D3D11_TEXTURE2D_DESC m_desc; }; diff --git a/src/d3d11/d3d11_view.cpp b/src/d3d11/d3d11_view.cpp new file mode 100644 index 00000000..7b1fabe8 --- /dev/null +++ b/src/d3d11/d3d11_view.cpp @@ -0,0 +1,45 @@ +#include "d3d11_device.h" +#include "d3d11_view.h" + +namespace dxvk { + + D3D11RenderTargetView::D3D11RenderTargetView( + D3D11Device* device, + const D3D11_RENDER_TARGET_VIEW_DESC& desc) + : m_device (device), + m_desc (desc) { + + } + + + D3D11RenderTargetView::~D3D11RenderTargetView() { + + } + + + HRESULT D3D11RenderTargetView::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); + COM_QUERY_IFACE(riid, ppvObject, ID3D11View); + COM_QUERY_IFACE(riid, ppvObject, ID3D11RenderTargetView); + + Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + void D3D11RenderTargetView::GetDevice(ID3D11Device** ppDevice) { + *ppDevice = m_device.ref(); + } + + + void D3D11RenderTargetView::GetResource(ID3D11Resource **ppResource) { + + } + + + void D3D11RenderTargetView::GetDesc(D3D11_RENDER_TARGET_VIEW_DESC* pDesc) { + *pDesc = m_desc; + } + +} diff --git a/src/d3d11/d3d11_view.h b/src/d3d11/d3d11_view.h new file mode 100644 index 00000000..b9b84d19 --- /dev/null +++ b/src/d3d11/d3d11_view.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "d3d11_device_child.h" + +namespace dxvk { + + class D3D11Device; + + class D3D11RenderTargetView : public D3D11DeviceChild { + + public: + + D3D11RenderTargetView( + D3D11Device* device, + const D3D11_RENDER_TARGET_VIEW_DESC& desc); + ~D3D11RenderTargetView(); + + HRESULT QueryInterface( + REFIID riid, + void** ppvObject) final; + + void GetDevice( + ID3D11Device **ppDevice) final; + + void GetResource( + ID3D11Resource **ppResource) final; + + void GetDesc( + D3D11_RENDER_TARGET_VIEW_DESC* pDesc) final; + + private: + + Com m_device; + D3D11_RENDER_TARGET_VIEW_DESC m_desc; + + }; + +} diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 9d2fbadf..085679ce 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -4,6 +4,7 @@ d3d11_src = [ 'd3d11_device.cpp', 'd3d11_main.cpp', 'd3d11_texture.cpp', + 'd3d11_view.cpp', ] d3d11_dll = shared_library('d3d11', d3d11_src, diff --git a/src/dxgi/dxgi_device.cpp b/src/dxgi/dxgi_device.cpp index 155f95df..c115c100 100644 --- a/src/dxgi/dxgi_device.cpp +++ b/src/dxgi/dxgi_device.cpp @@ -91,7 +91,7 @@ namespace dxvk { extern "C" { - DLLEXPORT HRESULT __stdcall DXGICreateDXVKDevice( + DLLEXPORT HRESULT __stdcall DXGICreateDevicePrivate( IDXGIAdapterPrivate* pAdapter, IDXGIDevicePrivate** ppDevice) { try { diff --git a/src/dxgi/dxgi_device.h b/src/dxgi/dxgi_device.h index d209cf33..657265b7 100644 --- a/src/dxgi/dxgi_device.h +++ b/src/dxgi/dxgi_device.h @@ -64,7 +64,7 @@ namespace dxvk { extern "C" { - DLLEXPORT HRESULT __stdcall DXGICreateDXVKDevice( + DLLEXPORT HRESULT __stdcall DXGICreateDevicePrivate( IDXGIAdapterPrivate* pAdapter, IDXGIDevicePrivate** ppDevice); diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index ebdeba6a..867d91ec 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -19,3 +19,12 @@ #include #include + +// For some reason, these are not exposed +#ifndef DXGI_RESOURCE_PRIORITY_NORMAL + #define DXGI_RESOURCE_PRIORITY_MINIMUM (0x28000000) + #define DXGI_RESOURCE_PRIORITY_LOW (0x50000000) + #define DXGI_RESOURCE_PRIORITY_NORMAL (0x78000000) + #define DXGI_RESOURCE_PRIORITY_HIGH (0xa0000000) + #define DXGI_RESOURCE_PRIORITY_MAXIMUM (0xc8000000) +#endif \ No newline at end of file diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index b66e849a..ba3645be 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -5,7 +5,9 @@ namespace dxvk { class DxgiAdapter; class DxvkAdapter; + class DxvkBuffer; class DxvkDevice; + class DxvkImage; } /** @@ -41,5 +43,37 @@ IDXGIDevicePrivate : public IDXGIDevice { }; -template<> inline GUID const& __mingw_uuidof() { return IDXGIAdapterPrivate::guid; } -template<> inline GUID const& __mingw_uuidof () { return IDXGIDevicePrivate ::guid; } +/** + * \brief Private buffer resource interface + * Provides access to a raw DXVK buffer. + */ +MIDL_INTERFACE("5679becd-8547-4d93-96a1-e61a1ce7ef37") +IDXGIBufferResourcePrivate : public IDXGIResource { + static const GUID guid; + + virtual dxvk::Rc GetDXVKBuffer() = 0; + + virtual void SetResourceLayer( + IUnknown* pLayer) = 0; +}; + + +/** + * \brief Private image resource interface + * Provides access to a raw DXVK image. + */ +MIDL_INTERFACE("1cfe6592-7de0-4a07-8dcb-4543cbbc6a7d") +IDXGIImageResourcePrivate : public IDXGIResource { + static const GUID guid; + + virtual dxvk::Rc GetDXVKImage() = 0; + + virtual void SetResourceLayer( + IUnknown* pLayer) = 0; +}; + + +DXVK_DEFINE_GUID(IDXGIAdapterPrivate); +DXVK_DEFINE_GUID(IDXGIDevicePrivate); +DXVK_DEFINE_GUID(IDXGIBufferResourcePrivate); +DXVK_DEFINE_GUID(IDXGIImageResourcePrivate); diff --git a/src/dxgi/dxgi_resource.cpp b/src/dxgi/dxgi_resource.cpp new file mode 100644 index 00000000..a7083645 --- /dev/null +++ b/src/dxgi/dxgi_resource.cpp @@ -0,0 +1,132 @@ +#include "dxgi_resource.h" + +namespace dxvk { + + DxgiImageResource::DxgiImageResource( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkImageCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags) + : Base(pDevice, usageFlags) { + m_image = pDevice->GetDXVKDevice()->createImage( + *pCreateInfo, memoryFlags); + } + + + DxgiImageResource::~DxgiImageResource() { + + } + + + HRESULT DxgiImageResource::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); + COM_QUERY_IFACE(riid, ppvObject, IDXGIDeviceSubObject); + COM_QUERY_IFACE(riid, ppvObject, IDXGIResource); + COM_QUERY_IFACE(riid, ppvObject, IDXGIImageResourcePrivate); + + Logger::err("DxgiImageResource::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + HRESULT DxgiImageResource::GetParent(REFIID riid, void** ppParent) { + Logger::err("DxgiImageResource::GetParent: Unknown interface query"); + return E_NOINTERFACE; + } + + + Rc DxgiImageResource::GetDXVKImage() { + return m_image; + } + + + void DxgiImageResource::SetResourceLayer(IUnknown* pLayer) { + m_layer = pLayer; + } + + + + + DxgiBufferResource::DxgiBufferResource( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkBufferCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags) + : Base(pDevice, usageFlags) { + m_buffer = pDevice->GetDXVKDevice()->createBuffer( + *pCreateInfo, memoryFlags); + } + + + DxgiBufferResource::~DxgiBufferResource() { + + } + + + HRESULT DxgiBufferResource::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); + COM_QUERY_IFACE(riid, ppvObject, IDXGIDeviceSubObject); + COM_QUERY_IFACE(riid, ppvObject, IDXGIResource); + COM_QUERY_IFACE(riid, ppvObject, IDXGIBufferResourcePrivate); + + Logger::err("DxgiBufferResource::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + HRESULT DxgiBufferResource::GetParent(REFIID riid, void** ppParent) { + Logger::err("DxgiBufferResource::GetParent: Unknown interface query"); + return E_NOINTERFACE; + } + + + Rc DxgiBufferResource::GetDXVKBuffer() { + return m_buffer; + } + + + void DxgiBufferResource::SetResourceLayer(IUnknown* pLayer) { + m_layer = pLayer; + } + +} + + +extern "C" { + + DLLEXPORT HRESULT __stdcall DXGICreateImageResourcePrivate( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkImageCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags, + IDXGIImageResourcePrivate** ppResource) { + try { + *ppResource = dxvk::ref(new dxvk::DxgiImageResource( + pDevice, pCreateInfo, memoryFlags, usageFlags)); + return S_OK; + } catch (const dxvk::DxvkError& e) { + dxvk::Logger::err(e.message()); + return DXGI_ERROR_UNSUPPORTED; + } + } + + + DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkBufferCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags, + IDXGIBufferResourcePrivate** ppResource) { + try { + *ppResource = dxvk::ref(new dxvk::DxgiBufferResource( + pDevice, pCreateInfo, memoryFlags, usageFlags)); + return S_OK; + } catch (const dxvk::DxvkError& e) { + dxvk::Logger::err(e.message()); + return DXGI_ERROR_UNSUPPORTED; + } + } + +} \ No newline at end of file diff --git a/src/dxgi/dxgi_resource.h b/src/dxgi/dxgi_resource.h new file mode 100644 index 00000000..9aefbcb3 --- /dev/null +++ b/src/dxgi/dxgi_resource.h @@ -0,0 +1,157 @@ +#pragma once + +#include + +#include "dxgi_object.h" +#include "dxgi_interfaces.h" + +namespace dxvk { + + template + class DxgiResource : public DxgiObject { + + public: + + DxgiResource( + IDXGIDevicePrivate* pDevice, + UINT usage) + : m_device (pDevice), + m_usageFlags(usage) { } + + HRESULT GetDevice(REFIID riid, void** ppDevice) { + return m_device->QueryInterface(riid, ppDevice); + } + + HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *pSharedHandle) { + Logger::err("DxgiResource::GetSharedHandle: Not implemented"); + return DXGI_ERROR_UNSUPPORTED; + } + + HRESULT STDMETHODCALLTYPE GetUsage(DXGI_USAGE *pUsage) { + if (pUsage == nullptr) + return DXGI_ERROR_INVALID_CALL; + + *pUsage = m_usageFlags; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) { + m_evictionPriority = EvictionPriority; + return S_OK; + } + + HRESULT STDMETHODCALLTYPE GetEvictionPriority(UINT *pEvictionPriority) { + if (pEvictionPriority == nullptr) + return DXGI_ERROR_INVALID_CALL; + + *pEvictionPriority = m_evictionPriority; + return S_OK; + } + + private: + + Com m_device; + + UINT m_evictionPriority = DXGI_RESOURCE_PRIORITY_NORMAL; + UINT m_usageFlags = 0; + + }; + + + /** + * \brief Image resource + * + * Stores a DXVK image and provides a method to retrieve + * it. D3D textures will be backed by an image resource. + */ + class DxgiImageResource : public DxgiResource { + using Base = DxgiResource; + public: + + DxgiImageResource( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkImageCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags); + + ~DxgiImageResource(); + + HRESULT QueryInterface( + REFIID riid, + void **ppvObject) final; + + HRESULT GetParent( + REFIID riid, + void **ppParent) final; + + Rc GetDXVKImage() final; + + void SetResourceLayer( + IUnknown* pLayer) final; + + private: + + Rc m_image; + IUnknown* m_layer = nullptr; + + }; + + + /** + * \brief Buffer resource + * + * Stores a DXVK buffer and provides a method to retrieve + * it. D3D buffers will be backed by a buffer resource. + */ + class DxgiBufferResource : public DxgiResource { + using Base = DxgiResource; + public: + + DxgiBufferResource( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkBufferCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags); + + ~DxgiBufferResource(); + + HRESULT QueryInterface( + REFIID riid, + void **ppvObject) final; + + HRESULT GetParent( + REFIID riid, + void **ppParent) final; + + Rc GetDXVKBuffer() final; + + void SetResourceLayer( + IUnknown* pLayer) final; + + private: + + Rc m_buffer; + IUnknown* m_layer = nullptr; + + }; + +} + + +extern "C" { + + DLLEXPORT HRESULT __stdcall DXGICreateImageResourcePrivate( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkImageCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags, + IDXGIImageResourcePrivate** ppResource); + + DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate( + IDXGIDevicePrivate* pDevice, + const dxvk::DxvkBufferCreateInfo* pCreateInfo, + VkMemoryPropertyFlags memoryFlags, + UINT usageFlags, + IDXGIBufferResourcePrivate** ppResource); + +} \ No newline at end of file diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 1837591a..06a0869a 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -1,4 +1,5 @@ #include "dxgi_factory.h" +#include "dxgi_resource.h" #include "dxgi_swapchain.h" namespace dxvk { @@ -12,7 +13,7 @@ namespace dxvk { // Retrieve a device pointer that allows us to // communicate with the underlying D3D device - if (FAILED(pDevice->QueryInterface(__uuidof(ID3D11DevicePrivate), + if (FAILED(pDevice->QueryInterface(__uuidof(IDXGIDevicePrivate), reinterpret_cast(&m_device)))) throw DxvkError("DxgiSwapChain::DxgiSwapChain: Invalid device"); @@ -188,15 +189,24 @@ namespace dxvk { HRESULT DxgiSwapChain::Present(UINT SyncInterval, UINT Flags) { std::lock_guard lock(m_mutex); + // TODO implement generic swap chain client interface + Com d3d11device; + + if (FAILED(m_device->QueryInterface(__uuidof(ID3D11DevicePrivate), + reinterpret_cast(&d3d11device)))) { + Logger::err("DxgiSwapChain::Present: Invalid swap chain client interface"); + return E_INVALIDARG; + } + try { // Submit pending rendering commands // before recording the present code. - m_device->FlushRenderingCommands(); + d3d11device->FlushRenderingCommands(); // TODO implement sync interval // TODO implement flags - auto dxvkDevice = m_device->GetDXVKDevice(); + auto dxvkDevice = d3d11device->GetDXVKDevice(); auto framebuffer = m_swapchain->getFramebuffer(m_acquireSync); auto framebufferSize = framebuffer->size(); @@ -351,8 +361,17 @@ namespace dxvk { // TODO support proper multi-sampling const Rc dxvkDevice = m_device->GetDXVKDevice(); + // TODO implement generic swap chain client interface + Com d3d11device; + + if (FAILED(m_device->QueryInterface(__uuidof(ID3D11DevicePrivate), + reinterpret_cast(&d3d11device)))) + throw DxvkError("DxgiSwapChain::Present: Invalid swap chain client interface"); + // Create an image that can be rendered to // and that can be used as a sampled texture. + Com resource; + DxvkImageCreateInfo imageInfo; imageInfo.type = VK_IMAGE_TYPE_2D; imageInfo.format = VK_FORMAT_R8G8B8A8_SNORM; @@ -380,8 +399,12 @@ namespace dxvk { | VK_ACCESS_SHADER_READ_BIT; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - m_backBuffer = dxvkDevice->createImage(imageInfo, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + if (FAILED(DXGICreateImageResourcePrivate(m_device.ptr(), &imageInfo, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, DXGI_USAGE_BACK_BUFFER | m_desc.BufferUsage, + &resource))) + throw DxvkError("DxgiSwapChain::createBackBuffer: Failed to create back buffer"); + + m_backBuffer = resource->GetDXVKImage(); // Create an image view that allows the // image to be bound as a shader resource. @@ -398,8 +421,8 @@ namespace dxvk { // Wrap the back buffer image into an interface // that the device can use to access the image. - if (FAILED(m_device->WrapSwapChainBackBuffer(m_backBuffer, &m_desc, &m_backBufferIface))) - throw DxvkError("DxgiSwapChain::createBackBuffer: Failed to create back buffer"); + if (FAILED(d3d11device->WrapSwapChainBackBuffer(resource.ptr(), &m_desc, &m_backBufferIface))) + throw DxvkError("DxgiSwapChain::createBackBuffer: Failed to create back buffer interface"); } } diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 00ee2c6c..4915e8f6 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -80,9 +80,9 @@ namespace dxvk { std::mutex m_mutex; - Com m_factory; - Com m_adapter; - Com m_device; + Com m_factory; + Com m_adapter; + Com m_device; DXGI_SWAP_CHAIN_DESC m_desc; DXGI_FRAME_STATISTICS m_stats; diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index fb8590cd..2049667b 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -4,6 +4,7 @@ dxgi_src = [ 'dxgi_factory.cpp', 'dxgi_main.cpp', 'dxgi_output.cpp', + 'dxgi_resource.cpp', 'dxgi_swapchain.cpp', ] diff --git a/src/util/com/com_guid.cpp b/src/util/com/com_guid.cpp index 1d653367..10a980ae 100644 --- a/src/util/com/com_guid.cpp +++ b/src/util/com/com_guid.cpp @@ -4,10 +4,12 @@ #include "../../dxgi/dxgi_interfaces.h" -const GUID IDXGIAdapterPrivate::guid = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}}; -const GUID IDXGIDevicePrivate::guid = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}}; +const GUID IDXGIAdapterPrivate::guid = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}}; +const GUID IDXGIDevicePrivate::guid = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}}; +const GUID IDXGIBufferResourcePrivate::guid = {0x5679becd,0x8547,0x4d93,{0x96,0xa1,0xe6,0x1a,0x1c,0xe7,0xef,0x37}}; +const GUID IDXGIImageResourcePrivate::guid = {0x1cfe6592,0x7de0,0x4a07,{0x8d,0xcb,0x45,0x43,0xcb,0xbc,0x6a,0x7d}}; -const GUID ID3D11DevicePrivate::guid = {0xab2a2a58,0xd2ac,0x4ca0,{0x9a,0xd9,0xa2,0x60,0xca,0xfa,0x00,0xc8}}; +const GUID ID3D11DevicePrivate::guid = {0xab2a2a58,0xd2ac,0x4ca0,{0x9a,0xd9,0xa2,0x60,0xca,0xfa,0x00,0xc8}}; std::ostream& operator << (std::ostream& os, REFIID guid) { os.width(8); diff --git a/src/util/com/com_object.h b/src/util/com/com_object.h index 9a6e7958..15561edb 100644 --- a/src/util/com/com_object.h +++ b/src/util/com/com_object.h @@ -22,11 +22,11 @@ namespace dxvk { virtual ~ComObject() { } - ULONG AddRef() final { + ULONG AddRef() { return ++m_refCount; } - ULONG Release() final { + ULONG Release() { ULONG refCount = --m_refCount; if (refCount == 0) delete this;