1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 10:24:12 +01:00

[d3d11] Implement IDXGIVkInteropDevice for D3D11Device

This commit is contained in:
Philip Rebohle 2018-04-20 00:19:03 +02:00
parent c2854e1fb9
commit 62b0e34a73
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
13 changed files with 253 additions and 1 deletions

View File

@ -2265,6 +2265,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

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

@ -221,7 +221,7 @@ IDXGIVkInteropDevice : public IUnknown {
* \param [in] OldLayout Current image layout
* \param [in] NewLayout Desired image layout
*/
virtual HRESULT STDMETHODCALLTYPE TransitionSurfaceLayout(
virtual void STDMETHODCALLTYPE TransitionSurfaceLayout(
IDXGIVkInteropSurface* pSurface,
const VkImageSubresourceRange* pSubresources,
VkImageLayout OldLayout,

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

@ -1199,6 +1199,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
*