1
0
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:
Philip Rebohle 2018-04-26 22:20:09 +02:00
commit 1784b8c44d
18 changed files with 582 additions and 19 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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
View 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
View 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;
};
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
};

View File

@ -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',

View File

@ -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

View File

@ -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);

View File

@ -52,6 +52,12 @@ namespace dxvk {
return m_handle;
}
/**
* \brief Vulkan instance
* \returns Vulkan instance
*/
Rc<DxvkInstance> instance() const;
/**
* \brief Physical device properties
*

View File

@ -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,

View File

@ -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
*

View File

@ -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) {

View File

@ -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;

View File

@ -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')