2026-03-15 03:02:15 +08:00
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
2026-03-15 23:03:06 +08:00
|
|
|
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12QueryHeap.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12RootSignature.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12SwapChain.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h"
|
|
|
|
|
#include "XCEngine/RHI/D3D12/D3D12ConstantBufferView.h"
|
2026-03-15 12:51:18 +08:00
|
|
|
#include <stdio.h>
|
2026-03-15 03:02:15 +08:00
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
#include <dxgidebug.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace XCEngine {
|
|
|
|
|
namespace RHI {
|
|
|
|
|
|
|
|
|
|
D3D12Device::D3D12Device()
|
|
|
|
|
: m_isDeviceRemoved(false)
|
|
|
|
|
, m_initialized(false)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
D3D12Device::~D3D12Device() {
|
|
|
|
|
Shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool D3D12Device::Initialize(bool enableDebugLayer) {
|
|
|
|
|
if (m_initialized) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!CreateDXGIFactory(enableDebugLayer)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ComPtr<IDXGIAdapter1> adapter;
|
|
|
|
|
int adapterIndex = 0;
|
|
|
|
|
bool adapterFound = false;
|
|
|
|
|
|
|
|
|
|
while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) {
|
|
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
|
|
|
|
adapter->GetDesc1(&desc);
|
|
|
|
|
|
|
|
|
|
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
|
|
|
|
|
adapterIndex++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr);
|
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
|
adapterFound = true;
|
|
|
|
|
m_adapter = adapter;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
adapterIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!adapterFound) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!CreateDevice(m_adapter.Get())) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 21:50:54 +08:00
|
|
|
QueryAdapterInfo();
|
2026-03-15 03:02:15 +08:00
|
|
|
m_initialized = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void D3D12Device::Shutdown() {
|
|
|
|
|
if (m_device) {
|
|
|
|
|
m_device.Reset();
|
|
|
|
|
}
|
|
|
|
|
if (m_factory) {
|
|
|
|
|
m_factory.Reset();
|
|
|
|
|
}
|
|
|
|
|
m_adapter.Reset();
|
|
|
|
|
m_initialized = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool D3D12Device::CreateDXGIFactory(bool enableDebugLayer) {
|
|
|
|
|
UINT dxgiFactoryFlags = 0;
|
|
|
|
|
|
2026-03-15 12:51:18 +08:00
|
|
|
{
|
2026-03-15 03:02:15 +08:00
|
|
|
ID3D12Debug* debugController = nullptr;
|
|
|
|
|
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) {
|
|
|
|
|
debugController->EnableDebugLayer();
|
|
|
|
|
dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
|
|
|
|
debugController->Release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT hr = CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&m_factory));
|
|
|
|
|
return SUCCEEDED(hr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool D3D12Device::CreateDevice(IDXGIAdapter1* adapter) {
|
2026-03-15 12:51:18 +08:00
|
|
|
OutputDebugStringA("[DEBUG] CreateDevice: start\n");
|
2026-03-15 03:02:15 +08:00
|
|
|
HRESULT hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
|
2026-03-15 12:51:18 +08:00
|
|
|
if (FAILED(hr)) {
|
|
|
|
|
char buf[256];
|
|
|
|
|
sprintf(buf, "[DEBUG] CreateDevice: D3D12CreateDevice failed! hr=%08X\n", hr);
|
|
|
|
|
OutputDebugStringA(buf);
|
|
|
|
|
}
|
2026-03-15 03:02:15 +08:00
|
|
|
return SUCCEEDED(hr);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-16 21:50:54 +08:00
|
|
|
void D3D12Device::QueryAdapterInfo() {
|
2026-03-15 03:02:15 +08:00
|
|
|
if (!m_adapter) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
|
|
|
|
m_adapter->GetDesc1(&desc);
|
|
|
|
|
|
2026-03-16 21:50:54 +08:00
|
|
|
m_adapterInfo.vendorId = desc.VendorId;
|
|
|
|
|
m_adapterInfo.deviceId = desc.DeviceId;
|
|
|
|
|
m_adapterInfo.dedicatedVideoMemory = desc.DedicatedVideoMemory;
|
|
|
|
|
m_adapterInfo.dedicatedSystemMemory = desc.DedicatedSystemMemory;
|
|
|
|
|
m_adapterInfo.sharedSystemMemory = desc.SharedSystemMemory;
|
|
|
|
|
m_adapterInfo.description = desc.Description;
|
|
|
|
|
m_adapterInfo.isSoftware = (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) != 0;
|
2026-03-15 03:02:15 +08:00
|
|
|
|
|
|
|
|
D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5 = {};
|
|
|
|
|
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5)))) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7 = {};
|
|
|
|
|
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)))) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool D3D12Device::CheckFeatureSupport(D3D12_FEATURE feature, void* featureSupportData, uint32_t featureSupportDataSize) {
|
|
|
|
|
return SUCCEEDED(m_device->CheckFeatureSupport(feature, featureSupportData, featureSupportDataSize));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<AdapterInfo> D3D12Device::EnumerateAdapters() {
|
|
|
|
|
std::vector<AdapterInfo> adapters;
|
|
|
|
|
|
|
|
|
|
if (!m_factory) {
|
|
|
|
|
return adapters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ComPtr<IDXGIAdapter1> adapter;
|
|
|
|
|
int adapterIndex = 0;
|
|
|
|
|
|
|
|
|
|
while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) {
|
|
|
|
|
DXGI_ADAPTER_DESC1 desc;
|
|
|
|
|
adapter->GetDesc1(&desc);
|
|
|
|
|
|
|
|
|
|
AdapterInfo info;
|
|
|
|
|
info.description = desc.Description;
|
|
|
|
|
info.dedicatedVideoMemory = desc.DedicatedVideoMemory;
|
|
|
|
|
info.dedicatedSystemMemory = desc.DedicatedSystemMemory;
|
|
|
|
|
info.sharedSystemMemory = desc.SharedSystemMemory;
|
|
|
|
|
info.vendorId = desc.VendorId;
|
|
|
|
|
info.deviceId = desc.DeviceId;
|
|
|
|
|
info.isSoftware = (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) != 0;
|
|
|
|
|
|
|
|
|
|
adapters.push_back(info);
|
|
|
|
|
adapterIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return adapters;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-15 20:31:37 +08:00
|
|
|
UINT D3D12Device::GetDescriptorHandleIncrementSize(DescriptorHeapType type) const {
|
|
|
|
|
return m_device->GetDescriptorHandleIncrementSize(ToD3D12(type));
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-15 23:03:06 +08:00
|
|
|
void* D3D12Device::GetNativeHandle() const {
|
|
|
|
|
return m_device.Get();
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-15 03:02:15 +08:00
|
|
|
} // namespace RHI
|
|
|
|
|
} // namespace XCEngine
|