mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d11] Implemented basic device creation
This commit is contained in:
parent
9b09184c9a
commit
024d69784d
@ -3,8 +3,12 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
D3D11DeviceContext::D3D11DeviceContext() {
|
D3D11DeviceContext::D3D11DeviceContext(
|
||||||
TRACE(this);
|
ID3D11Device* parent,
|
||||||
|
Rc<DxvkDevice> device)
|
||||||
|
: m_parent(parent),
|
||||||
|
m_device(device) {
|
||||||
|
TRACE(this, parent, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -24,7 +28,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11DeviceContext::GetDevice(ID3D11Device **ppDevice) {
|
void D3D11DeviceContext::GetDevice(ID3D11Device **ppDevice) {
|
||||||
Logger::warn("D3D11DeviceContext::GetDevice: Not implemented");
|
*ppDevice = ref(m_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,9 +13,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11DeviceContext();
|
D3D11DeviceContext(
|
||||||
|
ID3D11Device* parent,
|
||||||
|
Rc<DxvkDevice> device);
|
||||||
~D3D11DeviceContext();
|
~D3D11DeviceContext();
|
||||||
|
|
||||||
|
|
||||||
HRESULT QueryInterface(
|
HRESULT QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
@ -536,6 +537,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
ID3D11Device* const m_parent;
|
||||||
|
|
||||||
|
Rc<DxvkDevice> m_device;
|
||||||
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,28 +6,37 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
D3D11Device::D3D11Device(
|
D3D11Device::D3D11Device(
|
||||||
|
IDXVKDevice* dxgiDevice,
|
||||||
D3D_FEATURE_LEVEL featureLevel,
|
D3D_FEATURE_LEVEL featureLevel,
|
||||||
UINT featureFlags)
|
UINT featureFlags)
|
||||||
: m_featureLevel(featureLevel),
|
: m_dxgiDevice (dxgiDevice),
|
||||||
m_featureFlags(featureFlags) {
|
m_featureLevel(featureLevel),
|
||||||
TRACE(this, featureLevel, featureFlags);
|
m_featureFlags(featureFlags),
|
||||||
|
m_dxvkDevice (m_dxgiDevice->GetDXVKDevice()),
|
||||||
|
m_dxvkAdapter (m_dxvkDevice->adapter()) {
|
||||||
|
TRACE(this, dxgiDevice, featureLevel, featureFlags);
|
||||||
|
m_dxgiDevice->SetDeviceLayer(this);
|
||||||
|
m_context = new D3D11DeviceContext(this, m_dxvkDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11Device::~D3D11Device() {
|
D3D11Device::~D3D11Device() {
|
||||||
TRACE(this);
|
TRACE(this);
|
||||||
|
m_dxgiDevice->SetDeviceLayer(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11Device::QueryInterface(
|
HRESULT D3D11Device::QueryInterface(REFIID riid, void** ppvObject) {
|
||||||
REFIID riid,
|
|
||||||
void **ppvObject) {
|
|
||||||
COM_QUERY_IFACE(riid, ppvObject, ID3D11Device);
|
COM_QUERY_IFACE(riid, ppvObject, ID3D11Device);
|
||||||
|
|
||||||
|
if (riid == __uuidof(IDXVKDevice)
|
||||||
|
|| riid == __uuidof(IDXGIDevice))
|
||||||
|
return m_dxgiDevice->QueryInterface(riid, ppvObject);
|
||||||
|
|
||||||
Logger::warn("D3D11Device::QueryInterface: Unknown interface query");
|
Logger::warn("D3D11Device::QueryInterface: Unknown interface query");
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11Device::CreateBuffer(
|
HRESULT D3D11Device::CreateBuffer(
|
||||||
const D3D11_BUFFER_DESC* pDesc,
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
@ -314,19 +323,19 @@ namespace dxvk {
|
|||||||
|
|
||||||
HRESULT D3D11Device::GetPrivateData(
|
HRESULT D3D11Device::GetPrivateData(
|
||||||
REFGUID guid, UINT* pDataSize, void* pData) {
|
REFGUID guid, UINT* pDataSize, void* pData) {
|
||||||
return m_privateData.getData(guid, pDataSize, pData);
|
return m_dxgiDevice->GetPrivateData(guid, pDataSize, pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11Device::SetPrivateData(
|
HRESULT D3D11Device::SetPrivateData(
|
||||||
REFGUID guid, UINT DataSize, const void* pData) {
|
REFGUID guid, UINT DataSize, const void* pData) {
|
||||||
return m_privateData.setData(guid, DataSize, pData);
|
return m_dxgiDevice->SetPrivateData(guid, DataSize, pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11Device::SetPrivateDataInterface(
|
HRESULT D3D11Device::SetPrivateDataInterface(
|
||||||
REFGUID guid, const IUnknown* pData) {
|
REFGUID guid, const IUnknown* pData) {
|
||||||
return m_privateData.setInterface(guid, pData);
|
return m_dxgiDevice->SetPrivateDataInterface(guid, pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -347,7 +356,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11Device::GetImmediateContext(ID3D11DeviceContext** ppImmediateContext) {
|
void D3D11Device::GetImmediateContext(ID3D11DeviceContext** ppImmediateContext) {
|
||||||
Logger::err("D3D11Device::GetImmediateContext: Not implemented");
|
*ppImmediateContext = m_context.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -362,4 +371,10 @@ namespace dxvk {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool D3D11Device::CheckFeatureLevelSupport(
|
||||||
|
D3D_FEATURE_LEVEL featureLevel) {
|
||||||
|
return featureLevel <= D3D_FEATURE_LEVEL_11_0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <dxgi_object.h>
|
||||||
|
#include <dxgi_interfaces.h>
|
||||||
|
|
||||||
#include "d3d11_include.h"
|
#include "d3d11_include.h"
|
||||||
|
|
||||||
#include "../util/com/com_private_data.h"
|
#include "../util/com/com_private_data.h"
|
||||||
@ -14,13 +17,14 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11Device(
|
D3D11Device(
|
||||||
D3D_FEATURE_LEVEL featureLevel,
|
IDXVKDevice* dxgiDevice,
|
||||||
UINT featureFlags);
|
D3D_FEATURE_LEVEL featureLevel,
|
||||||
|
UINT featureFlags);
|
||||||
~D3D11Device();
|
~D3D11Device();
|
||||||
|
|
||||||
HRESULT QueryInterface(
|
HRESULT QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void **ppvObject) final;
|
void** ppvObject) final;
|
||||||
|
|
||||||
HRESULT CreateBuffer(
|
HRESULT CreateBuffer(
|
||||||
const D3D11_BUFFER_DESC* pDesc,
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
@ -185,18 +189,18 @@ namespace dxvk {
|
|||||||
UINT FeatureSupportDataSize) final;
|
UINT FeatureSupportDataSize) final;
|
||||||
|
|
||||||
HRESULT GetPrivateData(
|
HRESULT GetPrivateData(
|
||||||
REFGUID guid,
|
REFGUID Name,
|
||||||
UINT* pDataSize,
|
UINT *pDataSize,
|
||||||
void* pData) final;
|
void *pData) final;
|
||||||
|
|
||||||
HRESULT SetPrivateData(
|
HRESULT SetPrivateData(
|
||||||
REFGUID guid,
|
REFGUID Name,
|
||||||
UINT DataSize,
|
UINT DataSize,
|
||||||
const void* pData) final;
|
const void *pData) final;
|
||||||
|
|
||||||
HRESULT SetPrivateDataInterface(
|
HRESULT SetPrivateDataInterface(
|
||||||
REFGUID guid,
|
REFGUID Name,
|
||||||
const IUnknown* pData) final;
|
const IUnknown *pUnknown) final;
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL GetFeatureLevel() final;
|
D3D_FEATURE_LEVEL GetFeatureLevel() final;
|
||||||
|
|
||||||
@ -211,12 +215,19 @@ namespace dxvk {
|
|||||||
|
|
||||||
UINT GetExceptionMode() final;
|
UINT GetExceptionMode() final;
|
||||||
|
|
||||||
|
static bool CheckFeatureLevelSupport(
|
||||||
|
D3D_FEATURE_LEVEL featureLevel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const D3D_FEATURE_LEVEL m_featureLevel;
|
const Com<IDXVKDevice> m_dxgiDevice;
|
||||||
const UINT m_featureFlags;
|
const D3D_FEATURE_LEVEL m_featureLevel;
|
||||||
|
const UINT m_featureFlags;
|
||||||
|
|
||||||
ComPrivateData m_privateData;
|
const Rc<DxvkDevice> m_dxvkDevice;
|
||||||
|
const Rc<DxvkAdapter> m_dxvkAdapter;
|
||||||
|
|
||||||
|
Com<ID3D11DeviceContext> m_context;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
#include <array>
|
||||||
|
|
||||||
#include <dxgi_adapter.h>
|
#include <dxgi_adapter.h>
|
||||||
|
#include <dxgi_device.h>
|
||||||
|
|
||||||
#include "d3d11_device.h"
|
#include "d3d11_device.h"
|
||||||
|
|
||||||
using namespace dxvk;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
using namespace dxvk;
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall D3D11CreateDevice(
|
DLLEXPORT HRESULT __stdcall D3D11CreateDevice(
|
||||||
IDXGIAdapter *pAdapter,
|
IDXGIAdapter *pAdapter,
|
||||||
@ -21,8 +23,114 @@ extern "C" {
|
|||||||
Flags, pFeatureLevels, FeatureLevels,
|
Flags, pFeatureLevels, FeatureLevels,
|
||||||
SDKVersion, ppDevice, pFeatureLevel,
|
SDKVersion, ppDevice, pFeatureLevel,
|
||||||
ppImmediateContext);
|
ppImmediateContext);
|
||||||
Logger::err("D3D11CreateDevice: Not implemented");
|
|
||||||
return E_NOTIMPL;
|
Com<IDXGIAdapter> dxgiAdapter = pAdapter;
|
||||||
|
Com<IDXVKAdapter> dxvkAdapter = nullptr;
|
||||||
|
|
||||||
|
if (dxgiAdapter == nullptr) {
|
||||||
|
// We'll treat everything as hardware, even if the
|
||||||
|
// Vulkan device is actually a software device.
|
||||||
|
if (DriverType != D3D_DRIVER_TYPE_HARDWARE) {
|
||||||
|
Logger::err("D3D11CreateDevice: Unsupported driver type");
|
||||||
|
return DXGI_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll use the first adapter returned by a DXGI factory
|
||||||
|
Com<IDXGIFactory> factory = nullptr;
|
||||||
|
|
||||||
|
if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&factory)))) {
|
||||||
|
Logger::err("D3D11CreateDevice: Failed to create a DXGI factory");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(factory->EnumAdapters(0, &dxgiAdapter))) {
|
||||||
|
Logger::err("D3D11CreateDevice: No default adapter available");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// In theory we could ignore these, but the Microsoft docs explicitly
|
||||||
|
// state that we need to return E_INVALIDARG in case the arguments are
|
||||||
|
// invalid. Both the driver type and software parameter can only be
|
||||||
|
// set if the adapter itself is unspecified.
|
||||||
|
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082(v=vs.85).aspx
|
||||||
|
if (DriverType != D3D_DRIVER_TYPE_UNKNOWN || Software != nullptr)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The adapter must obviously be a DXVK-compatible adapter so
|
||||||
|
// that we can create a DXVK-compatible DXGI device from it.
|
||||||
|
if (FAILED(dxgiAdapter->QueryInterface(__uuidof(IDXVKAdapter),
|
||||||
|
reinterpret_cast<void**>(&dxvkAdapter)))) {
|
||||||
|
Logger::err("D3D11CreateDevice: Adapter is not a DXVK adapter");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature levels to probe if the
|
||||||
|
// application does not specify any.
|
||||||
|
std::array<D3D_FEATURE_LEVEL, 6> defaultFeatureLevels = {
|
||||||
|
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1,
|
||||||
|
D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3,
|
||||||
|
D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pFeatureLevels == nullptr || FeatureLevels == 0) {
|
||||||
|
pFeatureLevels = defaultFeatureLevels.data();
|
||||||
|
FeatureLevels = defaultFeatureLevels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the highest feature level supported by the device.
|
||||||
|
// This works because the feature level array is ordered.
|
||||||
|
UINT flId;
|
||||||
|
for (flId = 0 ; flId < FeatureLevels; flId++) {
|
||||||
|
if (D3D11Device::CheckFeatureLevelSupport(pFeatureLevels[flId]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flId == FeatureLevels) {
|
||||||
|
Logger::err("D3D11CreateDevice: Requested feature level not supported");
|
||||||
|
return DXGI_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to create the device with the given parameters.
|
||||||
|
const D3D_FEATURE_LEVEL fl = pFeatureLevels[flId];
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Write back the actual feature level
|
||||||
|
// if the application requested it.
|
||||||
|
if (pFeatureLevel != nullptr)
|
||||||
|
*pFeatureLevel = fl;
|
||||||
|
|
||||||
|
// The documentation is unclear about what exactly should be done if
|
||||||
|
// the application passes NULL to ppDevice, but a non-NULL pointer to
|
||||||
|
// ppImmediateContext. In our implementation, the immediate context
|
||||||
|
// does not hold a strong reference to the device that owns it, so
|
||||||
|
// if we cannot write back the device, it would be destroyed.
|
||||||
|
if (ppDevice != nullptr) {
|
||||||
|
Com<IDXVKDevice> dxvkDevice = nullptr;
|
||||||
|
|
||||||
|
if (FAILED(DXGICreateDXVKDevice(dxvkAdapter.ptr(), &dxvkDevice))) {
|
||||||
|
Logger::err("D3D11CreateDevice: Failed to create DXGI device");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com<D3D11Device> d3d11Device = new D3D11Device(
|
||||||
|
dxvkDevice.ptr(), fl, Flags);
|
||||||
|
|
||||||
|
*ppDevice = d3d11Device.ref();
|
||||||
|
if (ppImmediateContext != nullptr)
|
||||||
|
d3d11Device->GetImmediateContext(ppImmediateContext);
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
Logger::warn("D3D11CreateDevice: ppDevice is null");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const DxvkError& e) {
|
||||||
|
Logger::err("D3D11CreateDevice: Failed to create D3D11 device");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,8 +147,56 @@ extern "C" {
|
|||||||
ID3D11Device **ppDevice,
|
ID3D11Device **ppDevice,
|
||||||
D3D_FEATURE_LEVEL *pFeatureLevel,
|
D3D_FEATURE_LEVEL *pFeatureLevel,
|
||||||
ID3D11DeviceContext **ppImmediateContext) {
|
ID3D11DeviceContext **ppImmediateContext) {
|
||||||
Logger::err("D3D11CreateDeviceAndSwapChain: Not implemented");
|
TRACE(pAdapter, DriverType, Software,
|
||||||
return E_NOTIMPL;
|
Flags, pFeatureLevels, FeatureLevels,
|
||||||
|
SDKVersion, pSwapChainDesc, ppSwapChain,
|
||||||
|
ppDevice, pFeatureLevel, ppImmediateContext);
|
||||||
|
|
||||||
|
// Try to create a device first.
|
||||||
|
HRESULT status = D3D11CreateDevice(pAdapter, DriverType,
|
||||||
|
Software, Flags, pFeatureLevels, FeatureLevels,
|
||||||
|
SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Again, the documentation does not exactly tell us what we
|
||||||
|
// need to do in case one of the arguments is a null pointer.
|
||||||
|
if (ppDevice != nullptr && ppSwapChain != nullptr) {
|
||||||
|
if (pSwapChainDesc == nullptr)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
Com<ID3D11Device> d3d11Device = *ppDevice;
|
||||||
|
Com<IDXGIDevice> dxgiDevice = nullptr;
|
||||||
|
Com<IDXGIAdapter> dxgiAdapter = nullptr;
|
||||||
|
Com<IDXGIFactory> dxgiFactory = nullptr;
|
||||||
|
|
||||||
|
if (FAILED(d3d11Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)))) {
|
||||||
|
Logger::err("D3D11CreateDeviceAndSwapChain: Failed to query DXGI device");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter)))) {
|
||||||
|
Logger::err("D3D11CreateDeviceAndSwapChain: Failed to query DXGI adapter");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)))) {
|
||||||
|
Logger::err("D3D11CreateDeviceAndSwapChain: Failed to query DXGI factory");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc;
|
||||||
|
if (FAILED(dxgiFactory->CreateSwapChain(d3d11Device.ptr(), &desc, ppSwapChain))) {
|
||||||
|
Logger::err("D3D11CreateDeviceAndSwapChain: Failed to create swap chain");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
Logger::warn("D3D11CreateDeviceAndSwapChain: Not creating a swap chain");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,9 +5,11 @@ d3d11_src = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
d3d11_dll = shared_library('d3d11', d3d11_src,
|
d3d11_dll = shared_library('d3d11', d3d11_src,
|
||||||
|
name_prefix : '',
|
||||||
link_with : [ util_lib ],
|
link_with : [ util_lib ],
|
||||||
dependencies : [ dxvk_dep, dxgi_dep ],
|
dependencies : [ dxvk_dep, dxgi_dep ],
|
||||||
include_directories : dxvk_include_path)
|
include_directories : dxvk_include_path,
|
||||||
|
install : true)
|
||||||
|
|
||||||
d3d11_dep = declare_dependency(
|
d3d11_dep = declare_dependency(
|
||||||
link_with : [ d3d11_dll ],
|
link_with : [ d3d11_dll ],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user