mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 22:54:16 +01:00
[d3d11] Merge interop API
This commit is contained in:
commit
1784b8c44d
@ -2364,6 +2364,33 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11DeviceContext::TransitionSurfaceLayout(
|
||||
IDXGIVkInteropSurface* pSurface,
|
||||
const VkImageSubresourceRange* pSubresources,
|
||||
VkImageLayout OldLayout,
|
||||
VkImageLayout NewLayout) {
|
||||
// Get the underlying D3D11 resource
|
||||
Com<ID3D11Resource> resource;
|
||||
|
||||
pSurface->QueryInterface(__uuidof(ID3D11Resource),
|
||||
reinterpret_cast<void**>(&resource));
|
||||
|
||||
// Get the texture from that resource
|
||||
D3D11CommonTexture* texture = GetCommonTexture(resource.ptr());
|
||||
|
||||
EmitCs([
|
||||
cImage = texture->GetImage(),
|
||||
cSubresources = *pSubresources,
|
||||
cOldLayout = OldLayout,
|
||||
cNewLayout = NewLayout
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->transformImage(
|
||||
cImage, cSubresources,
|
||||
cOldLayout, cNewLayout);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::ApplyInputLayout() {
|
||||
if (m_state.ia.inputLayout != nullptr) {
|
||||
EmitCs([cInputLayout = m_state.ia.inputLayout] (DxvkContext* ctx) {
|
||||
|
@ -635,6 +635,12 @@ namespace dxvk {
|
||||
UINT NumBuffers,
|
||||
ID3D11Buffer** ppSOTargets) final;
|
||||
|
||||
void STDMETHODCALLTYPE TransitionSurfaceLayout(
|
||||
IDXGIVkInteropSurface* pSurface,
|
||||
const VkImageSubresourceRange* pSubresources,
|
||||
VkImageLayout OldLayout,
|
||||
VkImageLayout NewLayout);
|
||||
|
||||
protected:
|
||||
|
||||
D3D11Device* const m_parent;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "d3d11_context_imm.h"
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_input_layout.h"
|
||||
#include "d3d11_interop.h"
|
||||
#include "d3d11_present.h"
|
||||
#include "d3d11_query.h"
|
||||
#include "d3d11_sampler.h"
|
||||
@ -21,6 +22,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
D3D11DeviceContainer::~D3D11DeviceContainer() {
|
||||
delete m_d3d11VkInterop;
|
||||
delete m_d3d11Presenter;
|
||||
delete m_d3d11Device;
|
||||
delete m_dxgiDevice;
|
||||
@ -44,6 +46,11 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDXGIVkInteropDevice)) {
|
||||
*ppvObject = ref(m_d3d11VkInterop);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ID3D11Device)
|
||||
|| riid == __uuidof(ID3D11Device1)) {
|
||||
*ppvObject = ref(m_d3d11Device);
|
||||
|
@ -29,6 +29,7 @@ namespace dxvk {
|
||||
class D3D11Texture1D;
|
||||
class D3D11Texture2D;
|
||||
class D3D11Texture3D;
|
||||
class D3D11VkInterop;
|
||||
|
||||
/**
|
||||
* \brief D3D11 device container
|
||||
@ -54,6 +55,7 @@ namespace dxvk {
|
||||
IDXGIVkDevice* m_dxgiDevice = nullptr;
|
||||
D3D11Device* m_d3d11Device = nullptr;
|
||||
D3D11Presenter* m_d3d11Presenter = nullptr;
|
||||
D3D11VkInterop* m_d3d11VkInterop = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
107
src/d3d11/d3d11_interop.cpp
Normal file
107
src/d3d11/d3d11_interop.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "d3d11_context_imm.h"
|
||||
#include "d3d11_interop.h"
|
||||
#include "d3d11_device.h"
|
||||
|
||||
#include "../dxvk/dxvk_adapter.h"
|
||||
#include "../dxvk/dxvk_device.h"
|
||||
#include "../dxvk/dxvk_instance.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11VkInterop::D3D11VkInterop(
|
||||
IDXGIObject* pContainer,
|
||||
ID3D11Device* pDevice)
|
||||
: m_container (pContainer),
|
||||
m_device (pDevice) { }
|
||||
|
||||
|
||||
D3D11VkInterop::~D3D11VkInterop() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE D3D11VkInterop::AddRef() {
|
||||
return m_container->AddRef();
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE D3D11VkInterop::Release() {
|
||||
return m_container->Release();
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11VkInterop::QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) {
|
||||
return m_container->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::GetVulkanHandles(
|
||||
VkInstance* pInstance,
|
||||
VkPhysicalDevice* pPhysDev,
|
||||
VkDevice* pDevice) {
|
||||
auto device = static_cast<D3D11Device*>(m_device)->GetDXVKDevice();
|
||||
auto adapter = device->adapter();
|
||||
auto instance = adapter->instance();
|
||||
|
||||
if (pDevice != nullptr)
|
||||
*pDevice = device->handle();
|
||||
|
||||
if (pPhysDev != nullptr)
|
||||
*pPhysDev = adapter->handle();
|
||||
|
||||
if (pInstance != nullptr)
|
||||
*pInstance = instance->handle();
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::GetSubmissionQueue(
|
||||
VkQueue* pQueue,
|
||||
uint32_t* pQueueFamilyIndex) {
|
||||
auto device = static_cast<D3D11Device*>(m_device)->GetDXVKDevice();
|
||||
DxvkDeviceQueue queue = device->graphicsQueue();
|
||||
|
||||
if (pQueue != nullptr)
|
||||
*pQueue = queue.queueHandle;
|
||||
|
||||
if (pQueueFamilyIndex != nullptr)
|
||||
*pQueueFamilyIndex = queue.queueFamily;
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::TransitionSurfaceLayout(
|
||||
IDXGIVkInteropSurface* pSurface,
|
||||
const VkImageSubresourceRange* pSubresources,
|
||||
VkImageLayout OldLayout,
|
||||
VkImageLayout NewLayout) {
|
||||
Com<ID3D11DeviceContext> deviceContext = nullptr;
|
||||
m_device->GetImmediateContext(&deviceContext);
|
||||
|
||||
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
|
||||
|
||||
immediateContext->TransitionSurfaceLayout(
|
||||
pSurface, pSubresources, OldLayout, NewLayout);
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::FlushRenderingCommands() {
|
||||
Com<ID3D11DeviceContext> deviceContext = nullptr;
|
||||
m_device->GetImmediateContext(&deviceContext);
|
||||
|
||||
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
|
||||
immediateContext->Flush();
|
||||
immediateContext->SynchronizeCsThread();
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::LockSubmissionQueue() {
|
||||
static_cast<D3D11Device*>(m_device)->GetDXVKDevice()->lockSubmission();
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE D3D11VkInterop::ReleaseSubmissionQueue() {
|
||||
static_cast<D3D11Device*>(m_device)->GetDXVKDevice()->unlockSubmission();
|
||||
}
|
||||
|
||||
}
|
54
src/d3d11/d3d11_interop.h
Normal file
54
src/d3d11/d3d11_interop.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxgi/dxgi_interfaces.h"
|
||||
|
||||
#include "d3d11_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D11VkInterop : public ComObject<IDXGIVkInteropDevice> {
|
||||
|
||||
public:
|
||||
|
||||
D3D11VkInterop(
|
||||
IDXGIObject* pContainer,
|
||||
ID3D11Device* pDevice);
|
||||
~D3D11VkInterop();
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
void STDMETHODCALLTYPE GetVulkanHandles(
|
||||
VkInstance* pInstance,
|
||||
VkPhysicalDevice* pPhysDev,
|
||||
VkDevice* pDevice);
|
||||
|
||||
void STDMETHODCALLTYPE GetSubmissionQueue(
|
||||
VkQueue* pQueue,
|
||||
uint32_t* pQueueFamilyIndex);
|
||||
|
||||
void STDMETHODCALLTYPE TransitionSurfaceLayout(
|
||||
IDXGIVkInteropSurface* pSurface,
|
||||
const VkImageSubresourceRange* pSubresources,
|
||||
VkImageLayout OldLayout,
|
||||
VkImageLayout NewLayout);
|
||||
|
||||
void STDMETHODCALLTYPE FlushRenderingCommands();
|
||||
|
||||
void STDMETHODCALLTYPE LockSubmissionQueue();
|
||||
|
||||
void STDMETHODCALLTYPE ReleaseSubmissionQueue();
|
||||
|
||||
private:
|
||||
|
||||
IDXGIObject* m_container;
|
||||
ID3D11Device* m_device;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_enums.h"
|
||||
#include "d3d11_interop.h"
|
||||
#include "d3d11_present.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -127,6 +128,9 @@ extern "C" {
|
||||
container->m_d3d11Presenter = new D3D11Presenter(
|
||||
container.ptr(), container->m_d3d11Device);
|
||||
|
||||
container->m_d3d11VkInterop = new D3D11VkInterop(
|
||||
container.ptr(), container->m_d3d11Device);
|
||||
|
||||
if (ppDevice != nullptr)
|
||||
*ppDevice = ref(container->m_d3d11Device);
|
||||
|
||||
|
@ -284,12 +284,81 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
D3D11VkInteropSurface::D3D11VkInteropSurface(
|
||||
ID3D11DeviceChild* pContainer,
|
||||
D3D11CommonTexture* pTexture)
|
||||
: m_container (pContainer),
|
||||
m_texture (pTexture) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D11VkInteropSurface::~D3D11VkInteropSurface() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE D3D11VkInteropSurface::AddRef() {
|
||||
return m_container->AddRef();
|
||||
}
|
||||
|
||||
|
||||
ULONG STDMETHODCALLTYPE D3D11VkInteropSurface::Release() {
|
||||
return m_container->Release();
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11VkInteropSurface::QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) {
|
||||
return m_container->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D11VkInteropSurface::GetVulkanImageInfo(
|
||||
VkImage* pHandle,
|
||||
VkImageLayout* pLayout,
|
||||
VkImageCreateInfo* pInfo) {
|
||||
const Rc<DxvkImage> image = m_texture->GetImage();
|
||||
const DxvkImageCreateInfo& info = image->info();
|
||||
|
||||
if (pHandle != nullptr)
|
||||
*pHandle = image->handle();
|
||||
|
||||
if (pLayout != nullptr)
|
||||
*pLayout = info.layout;
|
||||
|
||||
if (pInfo != nullptr) {
|
||||
// We currently don't support any extended structures
|
||||
if (pInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
|
||||
|| pInfo->pNext != nullptr)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pInfo->flags = 0;
|
||||
pInfo->imageType = info.type;
|
||||
pInfo->format = info.format;
|
||||
pInfo->extent = info.extent;
|
||||
pInfo->mipLevels = info.mipLevels;
|
||||
pInfo->arrayLayers = info.numLayers;
|
||||
pInfo->samples = info.sampleCount;
|
||||
pInfo->tiling = info.tiling;
|
||||
pInfo->usage = info.usage;
|
||||
pInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
pInfo->queueFamilyIndexCount = 0;
|
||||
pInfo->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// D 3 D 1 1 T E X T U R E 1 D
|
||||
D3D11Texture1D::D3D11Texture1D(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D) {
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D),
|
||||
m_interop(this, &m_texture) {
|
||||
|
||||
}
|
||||
|
||||
@ -310,6 +379,11 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||
*ppvObject = ref(&m_interop);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query");
|
||||
Logger::warn(str::format(riid));
|
||||
return E_NOINTERFACE;
|
||||
@ -354,7 +428,8 @@ namespace dxvk {
|
||||
D3D11Texture2D::D3D11Texture2D(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D) {
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D),
|
||||
m_interop(this, &m_texture) {
|
||||
|
||||
}
|
||||
|
||||
@ -375,6 +450,11 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||
*ppvObject = ref(&m_interop);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query");
|
||||
Logger::warn(str::format(riid));
|
||||
return E_NOINTERFACE;
|
||||
@ -421,7 +501,8 @@ namespace dxvk {
|
||||
D3D11Texture3D::D3D11Texture3D(
|
||||
D3D11Device* pDevice,
|
||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D) {
|
||||
: m_texture(pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D),
|
||||
m_interop(this, &m_texture) {
|
||||
|
||||
}
|
||||
|
||||
@ -442,6 +523,11 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||
*ppvObject = ref(&m_interop);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query");
|
||||
Logger::warn(str::format(riid));
|
||||
return E_NOINTERFACE;
|
||||
|
@ -190,6 +190,43 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Common texture interop class
|
||||
*
|
||||
* Provides access to the underlying Vulkan
|
||||
* texture to external Vulkan libraries.
|
||||
*/
|
||||
class D3D11VkInteropSurface : public IDXGIVkInteropSurface {
|
||||
|
||||
public:
|
||||
|
||||
D3D11VkInteropSurface(
|
||||
ID3D11DeviceChild* pContainer,
|
||||
D3D11CommonTexture* pTexture);
|
||||
|
||||
~D3D11VkInteropSurface();
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetVulkanImageInfo(
|
||||
VkImage* pHandle,
|
||||
VkImageLayout* pLayout,
|
||||
VkImageCreateInfo* pInfo);
|
||||
|
||||
private:
|
||||
|
||||
ID3D11DeviceChild* m_container;
|
||||
D3D11CommonTexture* m_texture;
|
||||
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// D 3 D 1 1 T E X T U R E 1 D
|
||||
class D3D11Texture1D : public D3D11DeviceChild<ID3D11Texture1D> {
|
||||
@ -225,7 +262,8 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11VkInteropSurface m_interop;
|
||||
|
||||
};
|
||||
|
||||
@ -265,7 +303,8 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11VkInteropSurface m_interop;
|
||||
|
||||
};
|
||||
|
||||
@ -305,7 +344,8 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11CommonTexture m_texture;
|
||||
D3D11VkInteropSurface m_interop;
|
||||
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@ d3d11_src = [
|
||||
'd3d11_device.cpp',
|
||||
'd3d11_enums.cpp',
|
||||
'd3d11_input_layout.cpp',
|
||||
'd3d11_interop.cpp',
|
||||
'd3d11_main.cpp',
|
||||
'd3d11_options.cpp',
|
||||
'd3d11_present.cpp',
|
||||
|
@ -133,14 +133,149 @@ IDXGIVkPresenter : public IUnknown {
|
||||
void** ppDevice) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXGI surface interface for Vulkan interop
|
||||
*
|
||||
* Provides access to the backing resource of a
|
||||
* DXGI surface, which is typically a D3D texture.
|
||||
*/
|
||||
MIDL_INTERFACE("5546cf8c-77e7-4341-b05d-8d4d5000e77d")
|
||||
IDXGIVkInteropSurface : public IUnknown {
|
||||
static const GUID guid;
|
||||
|
||||
/**
|
||||
* \brief Retrieves Vulkan image info
|
||||
*
|
||||
* Retrieves both the image handle as well as the image's
|
||||
* properties. Any of the given pointers may be \c nullptr.
|
||||
*
|
||||
* If \c pInfo is not \c nullptr, the following rules apply:
|
||||
* - \c pInfo->sType \e must be \c VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
|
||||
* - \c pInfo->pNext \e must be \c nullptr or point to a supported
|
||||
* extension-specific structure (currently none)
|
||||
* - \c pInfo->queueFamilyIndexCount must be the length of the
|
||||
* \c pInfo->pQueueFamilyIndices array, in \c uint32_t units.
|
||||
* - \c pInfo->pQueueFamilyIndices must point to a pre-allocated
|
||||
* array of \c uint32_t of size \c pInfo->pQueueFamilyIndices.
|
||||
*
|
||||
* \note As of now, the sharing mode will always be
|
||||
* \c VK_SHARING_MODE_EXCLUSIVE and no queue
|
||||
* family indices will be written to the array.
|
||||
*
|
||||
* After the call, the structure pointed to by \c pInfo can
|
||||
* be used to create an image with identical properties.
|
||||
*
|
||||
* If \c pLayout is not \c nullptr, it will receive the
|
||||
* layout that the image will be in after flushing any
|
||||
* outstanding commands on the device.
|
||||
* \param [out] pHandle The image handle
|
||||
* \param [out] pLayout Image layout
|
||||
* \param [out] pInfo Image properties
|
||||
* \returns \c S_OK on success, or \c E_INVALIDARG
|
||||
*/
|
||||
virtual HRESULT STDMETHODCALLTYPE GetVulkanImageInfo(
|
||||
VkImage* pHandle,
|
||||
VkImageLayout* pLayout,
|
||||
VkImageCreateInfo* pInfo) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXGI device interface for Vulkan interop
|
||||
*
|
||||
* Provides access to the device and instance handles
|
||||
* as well as the queue that is used for rendering.
|
||||
*/
|
||||
MIDL_INTERFACE("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")
|
||||
IDXGIVkInteropDevice : public IUnknown {
|
||||
static const GUID guid;
|
||||
|
||||
/**
|
||||
* \brief Queries Vulkan handles used by DXVK
|
||||
*
|
||||
* \param [out] pInstance The Vulkan instance
|
||||
* \param [out] pPhysDev The physical device
|
||||
* \param [out] pDevide The device handle
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE GetVulkanHandles(
|
||||
VkInstance* pInstance,
|
||||
VkPhysicalDevice* pPhysDev,
|
||||
VkDevice* pDevice) = 0;
|
||||
|
||||
/**
|
||||
* \brief Queries the rendering queue used by DXVK
|
||||
*
|
||||
* \param [out] pQueue The Vulkan queue handle
|
||||
* \param [out] pQueueFamilyIndex Queue family index
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE GetSubmissionQueue(
|
||||
VkQueue* pQueue,
|
||||
uint32_t* pQueueFamilyIndex) = 0;
|
||||
|
||||
/**
|
||||
* \brief Transitions a surface to a given layout
|
||||
*
|
||||
* Executes an explicit image layout transition on the
|
||||
* D3D device. Note that the image subresources \e must
|
||||
* be transitioned back to its original layout before
|
||||
* using it again from D3D11.
|
||||
* \param [in] pSurface The image to transform
|
||||
* \param [in] pSubresources Subresources to transform
|
||||
* \param [in] OldLayout Current image layout
|
||||
* \param [in] NewLayout Desired image layout
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE TransitionSurfaceLayout(
|
||||
IDXGIVkInteropSurface* pSurface,
|
||||
const VkImageSubresourceRange* pSubresources,
|
||||
VkImageLayout OldLayout,
|
||||
VkImageLayout NewLayout) = 0;
|
||||
|
||||
/**
|
||||
* \brief Flushes outstanding D3D rendering commands
|
||||
*
|
||||
* Must be called before submitting Vulkan commands
|
||||
* to the rendering queue if those commands use the
|
||||
* backing resource of a D3D11 object.
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE FlushRenderingCommands() = 0;
|
||||
|
||||
/**
|
||||
* \brief Locks submission queue
|
||||
*
|
||||
* Should be called immediately before submitting
|
||||
* Vulkan commands to the rendering queue in order
|
||||
* to prevent DXVK from using the queue.
|
||||
*
|
||||
* While the submission queue is locked, no D3D11
|
||||
* methods must be called from the locking thread,
|
||||
* or otherwise a deadlock might occur.
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE LockSubmissionQueue() = 0;
|
||||
|
||||
/**
|
||||
* \brief Releases submission queue
|
||||
*
|
||||
* Should be called immediately after submitting
|
||||
* Vulkan commands to the rendering queue in order
|
||||
* to allow DXVK to submit new commands.
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE ReleaseSubmissionQueue() = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
struct __declspec(uuid("907bf281-ea3c-43b4-a8e4-9f231107b4ff")) IDXGIVkAdapter;
|
||||
struct __declspec(uuid("7a622cf6-627a-46b2-b52f-360ef3da831c")) IDXGIVkDevice;
|
||||
struct __declspec(uuid("5679becd-8547-4d93-96a1-e61a1ce7ef37")) IDXGIVkBackBuffer;
|
||||
struct __declspec(uuid("79352328-16f2-4f81-9746-9c2e2ccd43cf")) IDXGIVkPresenter;
|
||||
struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice;
|
||||
struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface;
|
||||
#else
|
||||
DXVK_DEFINE_GUID(IDXGIVkAdapter);
|
||||
DXVK_DEFINE_GUID(IDXGIVkDevice);
|
||||
DXVK_DEFINE_GUID(IDXGIVkBackBuffer);
|
||||
DXVK_DEFINE_GUID(IDXGIVkPresenter);
|
||||
DXVK_DEFINE_GUID(IDXGIVkInteropDevice);
|
||||
DXVK_DEFINE_GUID(IDXGIVkInteropSurface);
|
||||
#endif
|
@ -28,6 +28,11 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkInstance> DxvkAdapter::instance() const {
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
|
||||
VkPhysicalDeviceProperties DxvkAdapter::deviceProperties() const {
|
||||
VkPhysicalDeviceProperties properties;
|
||||
m_vki->vkGetPhysicalDeviceProperties(m_handle, &properties);
|
||||
|
@ -52,6 +52,12 @@ namespace dxvk {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Vulkan instance
|
||||
* \returns Vulkan instance
|
||||
*/
|
||||
Rc<DxvkInstance> instance() const;
|
||||
|
||||
/**
|
||||
* \brief Physical device properties
|
||||
*
|
||||
|
@ -1207,6 +1207,25 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::transformImage(
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const VkImageSubresourceRange& dstSubresources,
|
||||
VkImageLayout srcLayout,
|
||||
VkImageLayout dstLayout) {
|
||||
m_barriers.accessImage(
|
||||
dstImage, dstSubresources,
|
||||
srcLayout,
|
||||
dstImage->info().stages,
|
||||
dstImage->info().access,
|
||||
dstLayout,
|
||||
dstImage->info().stages,
|
||||
dstImage->info().access);
|
||||
m_barriers.recordCommands(m_cmd);
|
||||
|
||||
m_cmd->trackResource(dstImage);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
|
@ -468,6 +468,20 @@ namespace dxvk {
|
||||
const VkImageSubresourceLayers& srcSubresources,
|
||||
VkFormat format);
|
||||
|
||||
/**
|
||||
* \brief Transforms image subresource layouts
|
||||
*
|
||||
* \param [in] dstImage Image to transform
|
||||
* \param [in] dstSubresources Subresources
|
||||
* \param [in] srcLayout Current layout
|
||||
* \param [in] dstLayout Desired layout
|
||||
*/
|
||||
void transformImage(
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const VkImageSubresourceRange& dstSubresources,
|
||||
VkImageLayout srcLayout,
|
||||
VkImageLayout dstLayout);
|
||||
|
||||
/**
|
||||
* \brief Updates a buffer
|
||||
*
|
||||
|
@ -18,12 +18,16 @@ namespace dxvk {
|
||||
m_metaClearObjects(new DxvkMetaClearObjects (vkd)),
|
||||
m_unboundResources(this),
|
||||
m_submissionQueue (this) {
|
||||
m_graphicsQueue.queueFamily = m_adapter->graphicsQueueFamily();
|
||||
m_presentQueue.queueFamily = m_adapter->presentQueueFamily();
|
||||
|
||||
m_vkd->vkGetDeviceQueue(m_vkd->device(),
|
||||
m_adapter->graphicsQueueFamily(), 0,
|
||||
&m_graphicsQueue);
|
||||
m_graphicsQueue.queueFamily, 0,
|
||||
&m_graphicsQueue.queueHandle);
|
||||
|
||||
m_vkd->vkGetDeviceQueue(m_vkd->device(),
|
||||
m_adapter->presentQueueFamily(), 0,
|
||||
&m_presentQueue);
|
||||
m_presentQueue.queueFamily, 0,
|
||||
&m_presentQueue.queueHandle);
|
||||
}
|
||||
|
||||
|
||||
@ -202,7 +206,7 @@ namespace dxvk {
|
||||
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
||||
|
||||
m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1);
|
||||
return m_vkd->vkQueuePresentKHR(m_presentQueue, &presentInfo);
|
||||
return m_vkd->vkQueuePresentKHR(m_presentQueue.queueHandle, &presentInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +238,8 @@ namespace dxvk {
|
||||
m_statCounters.addCtr(DxvkStatCounter::QueueSubmitCount, 1);
|
||||
|
||||
status = commandList->submit(
|
||||
m_graphicsQueue, waitSemaphore, wakeSemaphore);
|
||||
m_graphicsQueue.queueHandle,
|
||||
waitSemaphore, wakeSemaphore);
|
||||
}
|
||||
|
||||
if (status == VK_SUCCESS) {
|
||||
|
@ -27,6 +27,17 @@ namespace dxvk {
|
||||
|
||||
class DxvkInstance;
|
||||
|
||||
/**
|
||||
* \brief Device queue
|
||||
*
|
||||
* Stores a Vulkan queue and the
|
||||
* queue family that it belongs to.
|
||||
*/
|
||||
struct DxvkDeviceQueue {
|
||||
uint32_t queueFamily = 0;
|
||||
VkQueue queueHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DXVK device
|
||||
*
|
||||
@ -66,6 +77,17 @@ namespace dxvk {
|
||||
return m_vkd->device();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Graphics queue properties
|
||||
*
|
||||
* Handle and queue family index of
|
||||
* the queue used for rendering.
|
||||
* \returns Graphics queue info
|
||||
*/
|
||||
DxvkDeviceQueue graphicsQueue() const {
|
||||
return m_graphicsQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The adapter
|
||||
*
|
||||
@ -291,6 +313,27 @@ namespace dxvk {
|
||||
const Rc<DxvkSemaphore>& waitSync,
|
||||
const Rc<DxvkSemaphore>& wakeSync);
|
||||
|
||||
/**
|
||||
* \brief Locks submission queue
|
||||
*
|
||||
* Since Vulkan queues are only meant to be accessed
|
||||
* from one thread at a time, external libraries need
|
||||
* to lock the queue before submitting command buffers.
|
||||
*/
|
||||
void lockSubmission() {
|
||||
m_submissionLock.lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unlocks submission queue
|
||||
*
|
||||
* Releases the Vulkan queues again so that DXVK
|
||||
* itself can use them for submissions again.
|
||||
*/
|
||||
void unlockSubmission() {
|
||||
m_submissionLock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Waits until the device becomes idle
|
||||
*
|
||||
@ -318,9 +361,9 @@ namespace dxvk {
|
||||
sync::Spinlock m_statLock;
|
||||
DxvkStatCounters m_statCounters;
|
||||
|
||||
std::mutex m_submissionLock;
|
||||
VkQueue m_graphicsQueue = VK_NULL_HANDLE;
|
||||
VkQueue m_presentQueue = VK_NULL_HANDLE;
|
||||
std::mutex m_submissionLock;
|
||||
DxvkDeviceQueue m_graphicsQueue;
|
||||
DxvkDeviceQueue m_presentQueue;
|
||||
|
||||
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
||||
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
||||
|
@ -4,10 +4,12 @@
|
||||
|
||||
#include "../../dxgi/dxgi_interfaces.h"
|
||||
|
||||
const GUID IDXGIVkAdapter::guid = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}};
|
||||
const GUID IDXGIVkDevice::guid = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}};
|
||||
const GUID IDXGIVkBackBuffer::guid = {0x5679becd,0x8547,0x4d93,{0x96,0xa1,0xe6,0x1a,0x1c,0xe7,0xef,0x37}};
|
||||
const GUID IDXGIVkPresenter::guid = {0x79352328,0x16f2,0x4f81,{0x97,0x46,0x9c,0x2e,0x2c,0xcd,0x43,0xcf}};
|
||||
const GUID IDXGIVkAdapter::guid = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}};
|
||||
const GUID IDXGIVkDevice::guid = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}};
|
||||
const GUID IDXGIVkBackBuffer::guid = {0x5679becd,0x8547,0x4d93,{0x96,0xa1,0xe6,0x1a,0x1c,0xe7,0xef,0x37}};
|
||||
const GUID IDXGIVkPresenter::guid = {0x79352328,0x16f2,0x4f81,{0x97,0x46,0x9c,0x2e,0x2c,0xcd,0x43,0xcf}};
|
||||
const GUID IDXGIVkInteropDevice::guid = {0xe2ef5fa5,0xdc21,0x4af7,{0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23}};
|
||||
const GUID IDXGIVkInteropSurface::guid = {0x5546cf8c,0x77e7,0x4341,{0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d}};
|
||||
|
||||
std::ostream& operator << (std::ostream& os, REFIID guid) {
|
||||
os << std::hex << std::setfill('0')
|
||||
|
Loading…
x
Reference in New Issue
Block a user