mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-04 16:24:29 +01:00
[d3d9] Add DxvkD3D8Bridge for d3d8 interop
This commit is contained in:
parent
b77928b6fe
commit
d6e7e3e780
103
src/d3d9/d3d9_bridge.cpp
Normal file
103
src/d3d9/d3d9_bridge.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
|
||||
#include "d3d9_device.h"
|
||||
#include "d3d9_interface.h"
|
||||
#include "d3d9_bridge.h"
|
||||
#include "d3d9_swapchain.h"
|
||||
#include "d3d9_surface.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxvkD3D8Bridge::DxvkD3D8Bridge(D3D9DeviceEx* pDevice)
|
||||
: m_device(pDevice) {
|
||||
}
|
||||
|
||||
DxvkD3D8Bridge::~DxvkD3D8Bridge() {
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::AddRef() {
|
||||
return m_device->AddRef();
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::Release() {
|
||||
return m_device->Release();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxvkD3D8Bridge::QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) {
|
||||
return m_device->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
HRESULT DxvkD3D8Bridge::UpdateTextureFromBuffer(
|
||||
IDirect3DSurface9* pDestSurface,
|
||||
IDirect3DSurface9* pSrcSurface,
|
||||
const RECT* pSrcRect,
|
||||
const POINT* pDestPoint) {
|
||||
auto lock = m_device->LockDevice();
|
||||
|
||||
D3D9Surface* dst = static_cast<D3D9Surface*>(pDestSurface);
|
||||
D3D9Surface* src = static_cast<D3D9Surface*>(pSrcSurface);
|
||||
|
||||
if (unlikely(dst == nullptr || src == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
D3D9CommonTexture* srcTextureInfo = src->GetCommonTexture();
|
||||
D3D9CommonTexture* dstTextureInfo = dst->GetCommonTexture();
|
||||
|
||||
VkOffset3D srcOffset = { 0u, 0u, 0u };
|
||||
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
||||
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
||||
VkExtent3D extent = texLevelExtent;
|
||||
|
||||
srcOffset = { pSrcRect->left,
|
||||
pSrcRect->top,
|
||||
0u };
|
||||
|
||||
extent = { uint32_t(pSrcRect->right - pSrcRect->left), uint32_t(pSrcRect->bottom - pSrcRect->top), 1 };
|
||||
|
||||
// TODO: Validate extents like in D3D9DeviceEx::UpdateSurface
|
||||
|
||||
dstOffset = { pDestPoint->x,
|
||||
pDestPoint->y,
|
||||
0u };
|
||||
|
||||
|
||||
m_device->UpdateTextureFromBuffer(
|
||||
srcTextureInfo, dstTextureInfo,
|
||||
src->GetSubresource(), dst->GetSubresource(),
|
||||
srcOffset, extent, dstOffset
|
||||
);
|
||||
|
||||
dstTextureInfo->SetNeedsReadback(dst->GetSubresource(), true);
|
||||
|
||||
if (dstTextureInfo->IsAutomaticMip())
|
||||
m_device->MarkTextureMipsDirty(dstTextureInfo);
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
DxvkD3D8InterfaceBridge::DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject)
|
||||
: m_interface(pObject) {
|
||||
}
|
||||
|
||||
DxvkD3D8InterfaceBridge::~DxvkD3D8InterfaceBridge() {
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::AddRef() {
|
||||
return m_interface->AddRef();
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::Release() {
|
||||
return m_interface->Release();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject) {
|
||||
return m_interface->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
const Config* DxvkD3D8InterfaceBridge::GetConfig() const {
|
||||
return &m_interface->GetInstance()->config();
|
||||
}
|
||||
}
|
103
src/d3d9/d3d9_bridge.h
Normal file
103
src/d3d9/d3d9_bridge.h
Normal file
@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "../util/config/config.h"
|
||||
|
||||
#include "../vulkan/vulkan_loader.h"
|
||||
|
||||
/**
|
||||
* The D3D9 bridge allows D3D8 to access DXVK internals.
|
||||
* For Vulkan interop without needing DXVK internals, see d3d9_interop.h.
|
||||
*
|
||||
* NOTE: You must include "d3d9_include.h" or "d3d8_include.h" before this header.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief D3D9 device interface for D3D8 interop
|
||||
*/
|
||||
MIDL_INTERFACE("D3D9D3D8-42A9-4C1E-AA97-BEEFCAFE2000")
|
||||
IDxvkD3D8Bridge : public IUnknown {
|
||||
|
||||
// D3D8 keeps D3D9 objects contained in a namespace.
|
||||
#ifdef DXVK_D3D9_NAMESPACE
|
||||
using IDirect3DSurface9 = d3d9::IDirect3DSurface9;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Updates a D3D9 surface from a D3D9 buffer
|
||||
*
|
||||
* \param [in] pDestSurface Destination surface (typically in VRAM)
|
||||
* \param [in] pSrcSurface Source surface (typically in system memory)
|
||||
* \param [in] pSrcRect Source rectangle
|
||||
* \param [in] pDestPoint Destination (top-left) point
|
||||
*/
|
||||
virtual HRESULT UpdateTextureFromBuffer(
|
||||
IDirect3DSurface9* pDestSurface,
|
||||
IDirect3DSurface9* pSrcSurface,
|
||||
const RECT* pSrcRect,
|
||||
const POINT* pDestPoint) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief D3D9 instance interface for D3D8 interop
|
||||
*/
|
||||
MIDL_INTERFACE("D3D9D3D8-A407-773E-18E9-CAFEBEEF3000")
|
||||
IDxvkD3D8InterfaceBridge : public IUnknown {
|
||||
/**
|
||||
* \brief Retrieves the DXVK configuration
|
||||
* \returns The DXVK Config object
|
||||
*/
|
||||
virtual const dxvk::Config* GetConfig() const = 0;
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
struct DECLSPEC_UUID("D3D9D3D8-42A9-4C1E-AA97-BEEFCAFE2000") IDxvkD3D8Bridge;
|
||||
struct DECLSPEC_UUID("D3D9D3D8-A407-773E-18E9-CAFEBEEF3000") IDxvkD3D8InterfaceBridge;
|
||||
#else
|
||||
__CRT_UUID_DECL(IDxvkD3D8Bridge, 0xD3D9D3D8, 0x42A9, 0x4C1E, 0xAA, 0x97, 0xBE, 0xEF, 0xCA, 0xFE, 0x20, 0x00);
|
||||
__CRT_UUID_DECL(IDxvkD3D8InterfaceBridge, 0xD3D9D3D8, 0xA407, 0x773E, 0x18, 0xE9, 0xCA, 0xFE, 0xBE, 0xEF, 0x30, 0x00);
|
||||
#endif
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D9DeviceEx;
|
||||
class D3D9InterfaceEx;
|
||||
|
||||
class DxvkD3D8Bridge : public IDxvkD3D8Bridge {
|
||||
public:
|
||||
DxvkD3D8Bridge(D3D9DeviceEx* pDevice);
|
||||
~DxvkD3D8Bridge();
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
HRESULT UpdateTextureFromBuffer(
|
||||
IDirect3DSurface9* pDestSurface,
|
||||
IDirect3DSurface9* pSrcSurface,
|
||||
const RECT* pSrcRect,
|
||||
const POINT* pDestPoint);
|
||||
|
||||
private:
|
||||
D3D9DeviceEx* m_device;
|
||||
};
|
||||
|
||||
class DxvkD3D8InterfaceBridge : public IDxvkD3D8InterfaceBridge {
|
||||
public:
|
||||
DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject);
|
||||
~DxvkD3D8InterfaceBridge();
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
const Config* GetConfig() const;
|
||||
|
||||
protected:
|
||||
D3D9InterfaceEx* m_interface;
|
||||
};
|
||||
}
|
@ -56,7 +56,8 @@ namespace dxvk {
|
||||
, m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) )
|
||||
, m_csChunk ( AllocCsChunk() )
|
||||
, m_d3d9Interop ( this )
|
||||
, m_d3d9On12 ( this ) {
|
||||
, m_d3d9On12 ( this )
|
||||
, m_d3d8Bridge ( this ) {
|
||||
// If we can SWVP, then we use an extended constant set
|
||||
// as SWVP has many more slots available than HWVP.
|
||||
bool canSWVP = CanSWVP();
|
||||
@ -218,6 +219,11 @@ namespace dxvk {
|
||||
*ppvObject = ref(this);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDxvkD3D8Bridge)) {
|
||||
*ppvObject = ref(&m_d3d8Bridge);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ID3D9VkInteropDevice)) {
|
||||
*ppvObject = ref(&m_d3d9Interop);
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
#include "d3d9_bridge.h"
|
||||
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
@ -127,6 +129,7 @@ namespace dxvk {
|
||||
friend class D3D9SwapChainEx;
|
||||
friend class D3D9ConstantBuffer;
|
||||
friend class D3D9UserDefinedAnnotation;
|
||||
friend class DxvkD3D8Bridge;
|
||||
friend D3D9VkInteropDevice;
|
||||
public:
|
||||
|
||||
@ -1364,6 +1367,7 @@ namespace dxvk {
|
||||
|
||||
D3D9VkInteropDevice m_d3d9Interop;
|
||||
D3D9On12 m_d3d9On12;
|
||||
DxvkD3D8Bridge m_d3d8Bridge;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "d3d9_monitor.h"
|
||||
#include "d3d9_caps.h"
|
||||
#include "d3d9_device.h"
|
||||
#include "d3d9_bridge.h"
|
||||
|
||||
#include "../util/util_singleton.h"
|
||||
|
||||
@ -14,6 +15,7 @@ namespace dxvk {
|
||||
|
||||
D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended)
|
||||
: m_instance ( g_dxvkInstance.acquire() )
|
||||
, m_d3d8Bridge ( this )
|
||||
, m_extended ( bExtended )
|
||||
, m_d3d9Options ( nullptr, m_instance->config() )
|
||||
, m_d3d9Interop ( this ) {
|
||||
@ -86,6 +88,11 @@ namespace dxvk {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IDxvkD3D8InterfaceBridge)) {
|
||||
*ppvObject = ref(&m_d3d8Bridge);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ID3D9VkInteropInterface)) {
|
||||
*ppvObject = ref(&m_d3d9Interop);
|
||||
return S_OK;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "d3d9_adapter.h"
|
||||
#include "d3d9_bridge.h"
|
||||
#include "d3d9_interop.h"
|
||||
|
||||
#include "../dxvk/dxvk_instance.h"
|
||||
@ -140,6 +141,8 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkInstance> m_instance;
|
||||
|
||||
DxvkD3D8InterfaceBridge m_d3d8Bridge;
|
||||
|
||||
bool m_extended;
|
||||
|
||||
D3D9Options m_d3d9Options;
|
||||
|
@ -45,7 +45,8 @@ d3d9_src = [
|
||||
'd3d9_mem.cpp',
|
||||
'd3d9_window.cpp',
|
||||
'd3d9_interop.cpp',
|
||||
'd3d9_on_12.cpp'
|
||||
'd3d9_on_12.cpp',
|
||||
'd3d9_bridge.cpp'
|
||||
]
|
||||
|
||||
d3d9_ld_args = []
|
||||
|
Loading…
Reference in New Issue
Block a user