Move D3D12 cpp files to src/RHI/D3D12/ subdirectory
This commit is contained in:
159
engine/src/RHI/D3D12/D3D12Buffer.cpp
Normal file
159
engine/src/RHI/D3D12/D3D12Buffer.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12Buffer::D3D12Buffer() {
|
||||
}
|
||||
|
||||
D3D12Buffer::~D3D12Buffer() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12Buffer::Initialize(ID3D12Device* device, uint64_t size, D3D12_RESOURCE_STATES initialState, D3D12_HEAP_TYPE heapType) {
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = heapType;
|
||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
heapProperties.CreationNodeMask = 0;
|
||||
heapProperties.VisibleNodeMask = 0;
|
||||
|
||||
D3D12_RESOURCE_DESC bufferDesc = {};
|
||||
bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
bufferDesc.Alignment = 0;
|
||||
bufferDesc.Width = size;
|
||||
bufferDesc.Height = 1;
|
||||
bufferDesc.DepthOrArraySize = 1;
|
||||
bufferDesc.MipLevels = 1;
|
||||
bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
bufferDesc.SampleDesc.Count = 1;
|
||||
bufferDesc.SampleDesc.Quality = 0;
|
||||
bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
HRESULT hResult = device->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&bufferDesc,
|
||||
initialState,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_resource)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Buffer::InitializeFromExisting(ID3D12Resource* resource) {
|
||||
m_resource = resource;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Buffer::InitializeWithData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList,
|
||||
const void* data, uint64_t size, D3D12_RESOURCE_STATES finalState) {
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12_RESOURCE_DESC bufferDesc = {};
|
||||
bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
bufferDesc.Alignment = 0;
|
||||
bufferDesc.Width = size;
|
||||
bufferDesc.Height = 1;
|
||||
bufferDesc.DepthOrArraySize = 1;
|
||||
bufferDesc.MipLevels = 1;
|
||||
bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
bufferDesc.SampleDesc.Count = 1;
|
||||
bufferDesc.SampleDesc.Quality = 0;
|
||||
bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
HRESULT hResult = device->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&bufferDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_resource)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bufferDesc = m_resource->GetDesc();
|
||||
UINT64 memorySizeUsed = 0;
|
||||
UINT64 rowSizeInBytes = 0;
|
||||
UINT rowUsed = 0;
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT subresourceFootprint;
|
||||
device->GetCopyableFootprints(&bufferDesc, 0, 1, 0,
|
||||
&subresourceFootprint, &rowUsed, &rowSizeInBytes, &memorySizeUsed);
|
||||
|
||||
ID3D12Resource* tempBufferObject = nullptr;
|
||||
D3D12_HEAP_PROPERTIES d3dTempHeapProperties = {};
|
||||
d3dTempHeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
|
||||
D3D12_RESOURCE_DESC d3d12TempResourceDesc = {};
|
||||
d3d12TempResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
d3d12TempResourceDesc.Alignment = 0;
|
||||
d3d12TempResourceDesc.Width = memorySizeUsed;
|
||||
d3d12TempResourceDesc.Height = 1;
|
||||
d3d12TempResourceDesc.DepthOrArraySize = 1;
|
||||
d3d12TempResourceDesc.MipLevels = 1;
|
||||
d3d12TempResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
d3d12TempResourceDesc.SampleDesc.Count = 1;
|
||||
d3d12TempResourceDesc.SampleDesc.Quality = 0;
|
||||
d3d12TempResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
d3d12TempResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
hResult = device->CreateCommittedResource(
|
||||
&d3dTempHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&d3d12TempResourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&tempBufferObject)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE* pData;
|
||||
tempBufferObject->Map(0, nullptr, reinterpret_cast<void**>(&pData));
|
||||
BYTE* pDstTempBuffer = reinterpret_cast<BYTE*>(pData + subresourceFootprint.Offset);
|
||||
const BYTE* pSrcData = reinterpret_cast<const BYTE*>(data);
|
||||
memcpy(pDstTempBuffer, pSrcData, size);
|
||||
tempBufferObject->Unmap(0, nullptr);
|
||||
|
||||
commandList->CopyBufferRegion(m_resource.Get(), 0, tempBufferObject, 0, subresourceFootprint.Footprint.Width);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = m_resource.Get();
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
barrier.Transition.StateAfter = finalState;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12Buffer::Shutdown() {
|
||||
m_resource.Reset();
|
||||
}
|
||||
|
||||
void D3D12Buffer::UpdateData(const void* data, uint64_t size) {
|
||||
D3D12_RANGE range = { 0, static_cast<SIZE_T>(size) };
|
||||
unsigned char* pBuffer = nullptr;
|
||||
m_resource->Map(0, &range, reinterpret_cast<void**>(&pBuffer));
|
||||
memcpy(pBuffer, data, static_cast<size_t>(size));
|
||||
m_resource->Unmap(0, nullptr);
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
36
engine/src/RHI/D3D12/D3D12CommandAllocator.cpp
Normal file
36
engine/src/RHI/D3D12/D3D12CommandAllocator.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
|
||||
#include "XCEngine/RHI/D3D12/D3D12Enum.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12CommandAllocator::D3D12CommandAllocator()
|
||||
: m_type(CommandQueueType::Direct) {
|
||||
}
|
||||
|
||||
D3D12CommandAllocator::~D3D12CommandAllocator() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12CommandAllocator::Initialize(ID3D12Device* device, CommandQueueType type) {
|
||||
m_type = type;
|
||||
HRESULT hResult = device->CreateCommandAllocator(
|
||||
ToD3D12(type),
|
||||
IID_PPV_ARGS(&m_commandAllocator));
|
||||
return SUCCEEDED(hResult);
|
||||
}
|
||||
|
||||
void D3D12CommandAllocator::Shutdown() {
|
||||
m_commandAllocator.Reset();
|
||||
}
|
||||
|
||||
void D3D12CommandAllocator::Reset() {
|
||||
m_commandAllocator->Reset();
|
||||
}
|
||||
|
||||
bool D3D12CommandAllocator::IsReady() const {
|
||||
return m_commandAllocator != nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
347
engine/src/RHI/D3D12/D3D12CommandList.cpp
Normal file
347
engine/src/RHI/D3D12/D3D12CommandList.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12CommandList::D3D12CommandList()
|
||||
: m_type(CommandQueueType::Direct)
|
||||
, m_currentTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
||||
, m_currentPipelineState(nullptr)
|
||||
, m_currentRootSignature(nullptr)
|
||||
, m_currentDescriptorHeap(nullptr) {
|
||||
}
|
||||
|
||||
D3D12CommandList::~D3D12CommandList() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12CommandList::Initialize(ID3D12Device* device, CommandQueueType type, ID3D12CommandAllocator* allocator) {
|
||||
D3D12_COMMAND_LIST_TYPE listType = ToD3D12(type);
|
||||
|
||||
HRESULT hResult = device->CreateCommandList(
|
||||
0,
|
||||
listType,
|
||||
allocator,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_commandList)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12CommandList::Shutdown() {
|
||||
m_commandList.Reset();
|
||||
m_resourceStateMap.clear();
|
||||
m_trackedResources.clear();
|
||||
}
|
||||
|
||||
void D3D12CommandList::Reset(ID3D12CommandAllocator* allocator) {
|
||||
m_commandList->Reset(allocator, nullptr);
|
||||
|
||||
m_currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
m_currentPipelineState = nullptr;
|
||||
m_currentRootSignature = nullptr;
|
||||
m_currentDescriptorHeap = nullptr;
|
||||
}
|
||||
|
||||
void D3D12CommandList::Close() {
|
||||
m_commandList->Close();
|
||||
}
|
||||
|
||||
void D3D12CommandList::TransitionBarrier(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter, uint32_t subresource) {
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = resource;
|
||||
barrier.Transition.StateBefore = ToD3D12(stateBefore);
|
||||
barrier.Transition.StateAfter = ToD3D12(stateAfter);
|
||||
barrier.Transition.Subresource = subresource;
|
||||
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
|
||||
m_resourceStateMap[resource] = stateAfter;
|
||||
}
|
||||
|
||||
void D3D12CommandList::UAVBarrier(ID3D12Resource* resource) {
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.UAV.pResource = resource;
|
||||
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
void D3D12CommandList::AliasBarrier(ID3D12Resource* beforeResource, ID3D12Resource* afterResource) {
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Aliasing.pResourceBefore = beforeResource;
|
||||
barrier.Aliasing.pResourceAfter = afterResource;
|
||||
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetPipelineState(ID3D12PipelineState* pso) {
|
||||
m_commandList->SetPipelineState(pso);
|
||||
m_currentPipelineState = pso;
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetRootSignature(ID3D12RootSignature* signature) {
|
||||
m_commandList->SetGraphicsRootSignature(signature);
|
||||
m_currentRootSignature = signature;
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetViewport(const Viewport& viewport) {
|
||||
D3D12_VIEWPORT d3d12Viewport = {};
|
||||
d3d12Viewport.TopLeftX = viewport.topLeftX;
|
||||
d3d12Viewport.TopLeftY = viewport.topLeftY;
|
||||
d3d12Viewport.Width = viewport.width;
|
||||
d3d12Viewport.Height = viewport.height;
|
||||
d3d12Viewport.MinDepth = viewport.minDepth;
|
||||
d3d12Viewport.MaxDepth = viewport.maxDepth;
|
||||
|
||||
m_commandList->RSSetViewports(1, &d3d12Viewport);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetViewports(uint32_t count, const Viewport* viewports) {
|
||||
std::vector<D3D12_VIEWPORT> d3d12Viewports(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
d3d12Viewports[i].TopLeftX = viewports[i].topLeftX;
|
||||
d3d12Viewports[i].TopLeftY = viewports[i].topLeftY;
|
||||
d3d12Viewports[i].Width = viewports[i].width;
|
||||
d3d12Viewports[i].Height = viewports[i].height;
|
||||
d3d12Viewports[i].MinDepth = viewports[i].minDepth;
|
||||
d3d12Viewports[i].MaxDepth = viewports[i].maxDepth;
|
||||
}
|
||||
|
||||
m_commandList->RSSetViewports(count, d3d12Viewports.data());
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetScissorRect(const Rect& rect) {
|
||||
D3D12_RECT d3d12Rect = {};
|
||||
d3d12Rect.left = rect.left;
|
||||
d3d12Rect.top = rect.top;
|
||||
d3d12Rect.right = rect.right;
|
||||
d3d12Rect.bottom = rect.bottom;
|
||||
|
||||
m_commandList->RSSetScissorRects(1, &d3d12Rect);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetScissorRects(uint32_t count, const Rect* rects) {
|
||||
std::vector<D3D12_RECT> d3d12Rects(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
d3d12Rects[i].left = rects[i].left;
|
||||
d3d12Rects[i].top = rects[i].top;
|
||||
d3d12Rects[i].right = rects[i].right;
|
||||
d3d12Rects[i].bottom = rects[i].bottom;
|
||||
}
|
||||
|
||||
m_commandList->RSSetScissorRects(count, d3d12Rects.data());
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetPrimitiveTopology(PrimitiveTopology topology) {
|
||||
m_commandList->IASetPrimitiveTopology(ToD3D12Topology(topology));
|
||||
m_currentTopology = ToD3D12Topology(topology);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetRenderTargets(uint32_t count, ID3D12Resource** renderTargets, ID3D12Resource* depthStencil) {
|
||||
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> rtvHandles(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
rtvHandles[i].ptr = 0;
|
||||
}
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {};
|
||||
dsvHandle.ptr = 0;
|
||||
|
||||
m_commandList->OMSetRenderTargets(count, count > 0 ? rtvHandles.data() : nullptr, FALSE, depthStencil ? &dsvHandle : nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetRenderTargets(uint32_t count, const D3D12_CPU_DESCRIPTOR_HANDLE* renderTargetHandles, const D3D12_CPU_DESCRIPTOR_HANDLE* depthStencilHandle) {
|
||||
m_commandList->OMSetRenderTargets(count, renderTargetHandles, FALSE, depthStencilHandle);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetVertexBuffer(uint32_t slot, ID3D12Resource* buffer, uint64_t offset, uint32_t stride) {
|
||||
D3D12_VERTEX_BUFFER_VIEW view = {};
|
||||
view.BufferLocation = buffer->GetGPUVirtualAddress() + offset;
|
||||
view.SizeInBytes = static_cast<UINT>(buffer->GetDesc().Width) - static_cast<UINT>(offset);
|
||||
view.StrideInBytes = stride;
|
||||
|
||||
m_commandList->IASetVertexBuffers(slot, 1, &view);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, const D3D12_VERTEX_BUFFER_VIEW* views) {
|
||||
m_commandList->IASetVertexBuffers(startSlot, count, views);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetIndexBuffer(ID3D12Resource* buffer, uint64_t offset, Format indexFormat) {
|
||||
D3D12_INDEX_BUFFER_VIEW view = {};
|
||||
view.BufferLocation = buffer->GetGPUVirtualAddress() + offset;
|
||||
view.SizeInBytes = static_cast<UINT>(buffer->GetDesc().Width) - static_cast<UINT>(offset);
|
||||
view.Format = ToD3D12(indexFormat);
|
||||
|
||||
m_commandList->IASetIndexBuffer(&view);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetDescriptorHeap(ID3D12DescriptorHeap* heap) {
|
||||
m_commandList->SetDescriptorHeaps(1, &heap);
|
||||
m_currentDescriptorHeap = heap;
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetDescriptorHeaps(uint32_t count, ID3D12DescriptorHeap** heaps) {
|
||||
m_commandList->SetDescriptorHeaps(count, heaps);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetGraphicsDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle) {
|
||||
m_commandList->SetGraphicsRootDescriptorTable(rootParameterIndex, baseHandle);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetComputeDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseHandle) {
|
||||
m_commandList->SetComputeRootDescriptorTable(rootParameterIndex, baseHandle);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetGraphicsRootConstantBufferView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
|
||||
m_commandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetGraphicsRoot32BitConstants(uint32_t rootParameterIndex, uint32_t num32BitValuesToSet, const void* pSrcData, uint32_t destOffsetIn32BitValues) {
|
||||
m_commandList->SetGraphicsRoot32BitConstants(rootParameterIndex, num32BitValuesToSet, pSrcData, destOffsetIn32BitValues);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetGraphicsRootDescriptorTable(uint32_t rootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor) {
|
||||
m_commandList->SetGraphicsRootDescriptorTable(rootParameterIndex, baseDescriptor);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetGraphicsRootShaderResourceView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS shaderResource) {
|
||||
m_commandList->SetGraphicsRootShaderResourceView(rootParameterIndex, shaderResource);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetStencilRef(uint32_t stencilRef) {
|
||||
m_commandList->OMSetStencilRef(stencilRef);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetBlendFactor(const float blendFactor[4]) {
|
||||
m_commandList->OMSetBlendFactor(blendFactor);
|
||||
}
|
||||
|
||||
void D3D12CommandList::SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp) {
|
||||
}
|
||||
|
||||
void D3D12CommandList::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) {
|
||||
m_commandList->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
|
||||
}
|
||||
|
||||
void D3D12CommandList::DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) {
|
||||
m_commandList->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex, startInstance);
|
||||
}
|
||||
|
||||
void D3D12CommandList::DrawInstancedIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset) {
|
||||
m_commandList->ExecuteIndirect(nullptr, 1, argBuffer, alignedByteOffset, nullptr, 0);
|
||||
}
|
||||
|
||||
void D3D12CommandList::DrawIndexedInstancedIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset) {
|
||||
m_commandList->ExecuteIndirect(nullptr, 1, argBuffer, alignedByteOffset, nullptr, 0);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearRenderTargetView(ID3D12Resource* renderTarget, const float color[4], uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = {};
|
||||
m_commandList->ClearRenderTargetView(rtvHandle, color, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE renderTargetHandle, const float color[4], uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
m_commandList->ClearRenderTargetView(renderTargetHandle, color, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearDepthStencilView(ID3D12Resource* depthStencil, uint32_t clearFlags, float depth, uint8_t stencil, uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {};
|
||||
m_commandList->ClearDepthStencilView(dsvHandle, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), depth, stencil, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE depthStencilHandle, uint32_t clearFlags, float depth, uint8_t stencil, uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
m_commandList->ClearDepthStencilView(depthStencilHandle, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), depth, stencil, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ClearUnorderedAccessView(D3D12_GPU_DESCRIPTOR_HANDLE viewHandle, D3D12_CPU_DESCRIPTOR_HANDLE resourceHandle, ID3D12Resource* unorderedAccess, const float values[4], uint32_t rectCount, const D3D12_RECT* rects) {
|
||||
m_commandList->ClearUnorderedAccessViewFloat(viewHandle, resourceHandle, unorderedAccess, values, rectCount, rects);
|
||||
}
|
||||
|
||||
void D3D12CommandList::CopyResource(ID3D12Resource* dst, ID3D12Resource* src) {
|
||||
m_commandList->CopyResource(dst, src);
|
||||
}
|
||||
|
||||
void D3D12CommandList::CopyBuffer(ID3D12Resource* dst, uint64_t dstOffset, ID3D12Resource* src, uint64_t srcOffset, uint64_t size) {
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||
srcLocation.pResource = src;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Offset = srcOffset;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = static_cast<UINT>(size);
|
||||
srcLocation.PlacedFootprint.Footprint.Height = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.RowPitch = static_cast<UINT>(size);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||
dstLocation.pResource = dst;
|
||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
dstLocation.PlacedFootprint.Offset = dstOffset;
|
||||
dstLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_UNKNOWN;
|
||||
dstLocation.PlacedFootprint.Footprint.Width = static_cast<UINT>(size);
|
||||
dstLocation.PlacedFootprint.Footprint.Height = 1;
|
||||
dstLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
dstLocation.PlacedFootprint.Footprint.RowPitch = static_cast<UINT>(size);
|
||||
|
||||
m_commandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::CopyTexture(ID3D12Resource* dst, const D3D12_TEXTURE_COPY_LOCATION& dstLocation, ID3D12Resource* src, const D3D12_TEXTURE_COPY_LOCATION& srcLocation) {
|
||||
m_commandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
|
||||
}
|
||||
|
||||
void D3D12CommandList::BeginQuery(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t index) {
|
||||
m_commandList->BeginQuery(queryHeap, ToD3D12(type), index);
|
||||
}
|
||||
|
||||
void D3D12CommandList::EndQuery(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t index) {
|
||||
m_commandList->EndQuery(queryHeap, ToD3D12(type), index);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ResolveQueryData(ID3D12QueryHeap* queryHeap, QueryType type, uint32_t startIndex, uint32_t count, ID3D12Resource* resultBuffer, uint64_t resultOffset) {
|
||||
m_commandList->ResolveQueryData(queryHeap, ToD3D12(type), startIndex, count, resultBuffer, resultOffset);
|
||||
}
|
||||
|
||||
void D3D12CommandList::Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) {
|
||||
m_commandList->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
}
|
||||
|
||||
void D3D12CommandList::DispatchIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset) {
|
||||
m_commandList->ExecuteIndirect(nullptr, 1, argBuffer, alignedByteOffset, nullptr, 0);
|
||||
}
|
||||
|
||||
void D3D12CommandList::ExecuteBundle(ID3D12GraphicsCommandList* bundle) {
|
||||
m_commandList->ExecuteBundle(bundle);
|
||||
}
|
||||
|
||||
ResourceStates D3D12CommandList::GetResourceState(ID3D12Resource* resource) const {
|
||||
auto it = m_resourceStateMap.find(resource);
|
||||
if (it != m_resourceStateMap.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return ResourceStates::Common;
|
||||
}
|
||||
|
||||
void D3D12CommandList::TrackResource(ID3D12Resource* resource) {
|
||||
if (resource) {
|
||||
m_trackedResources.push_back(resource);
|
||||
if (m_resourceStateMap.find(resource) == m_resourceStateMap.end()) {
|
||||
m_resourceStateMap[resource] = ResourceStates::Common;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
65
engine/src/RHI/D3D12/D3D12CommandQueue.cpp
Normal file
65
engine/src/RHI/D3D12/D3D12CommandQueue.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12CommandQueue::D3D12CommandQueue()
|
||||
: m_timestampFrequency(0)
|
||||
, m_type(CommandQueueType::Direct) {
|
||||
}
|
||||
|
||||
D3D12CommandQueue::~D3D12CommandQueue() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12CommandQueue::Initialize(ID3D12Device* device, CommandQueueType type) {
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Type = ToD3D12(type);
|
||||
queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 0;
|
||||
|
||||
HRESULT hResult = device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
m_commandQueue->GetTimestampFrequency(&m_timestampFrequency);
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::Shutdown() {
|
||||
m_commandQueue.Reset();
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, ID3D12CommandList** lists) {
|
||||
m_commandQueue->ExecuteCommandLists(count, lists);
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::Signal(ID3D12Fence* fence, uint64_t value) {
|
||||
m_commandQueue->Signal(fence, value);
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::Wait(ID3D12Fence* fence, uint64_t value) {
|
||||
m_commandQueue->Wait(fence, value);
|
||||
}
|
||||
|
||||
uint64_t D3D12CommandQueue::GetCompletedValue(ID3D12Fence* fence) {
|
||||
if (fence) {
|
||||
return fence->GetCompletedValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::WaitForIdle() {
|
||||
ID3D12Fence* fence = nullptr;
|
||||
HRESULT hResult = m_commandQueue->GetDevice(IID_PPV_ARGS(&fence));
|
||||
if (SUCCEEDED(hResult)) {
|
||||
m_commandQueue->Wait(fence, UINT64_MAX);
|
||||
fence->Release();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
35
engine/src/RHI/D3D12/D3D12ConstantBufferView.cpp
Normal file
35
engine/src/RHI/D3D12/D3D12ConstantBufferView.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12ConstantBufferView.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12ConstantBufferView::D3D12ConstantBufferView()
|
||||
: m_handle({0})
|
||||
, m_resource(nullptr) {
|
||||
}
|
||||
|
||||
D3D12ConstantBufferView::~D3D12ConstantBufferView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void D3D12ConstantBufferView::Initialize(ID3D12Device* device, ID3D12Resource* buffer, const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc) {
|
||||
m_resource = buffer;
|
||||
m_handle = {};
|
||||
|
||||
if (desc) {
|
||||
device->CreateConstantBufferView(desc, m_handle);
|
||||
} else {
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
|
||||
cbvDesc.BufferLocation = buffer->GetGPUVirtualAddress();
|
||||
cbvDesc.SizeInBytes = static_cast<UINT>(buffer->GetDesc().Width);
|
||||
device->CreateConstantBufferView(&cbvDesc, m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12ConstantBufferView::Shutdown() {
|
||||
m_handle = {};
|
||||
m_resource = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
33
engine/src/RHI/D3D12/D3D12DepthStencilView.cpp
Normal file
33
engine/src/RHI/D3D12/D3D12DepthStencilView.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12DepthStencilView::D3D12DepthStencilView()
|
||||
: m_handle({0})
|
||||
, m_resource(nullptr) {
|
||||
}
|
||||
|
||||
D3D12DepthStencilView::~D3D12DepthStencilView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void D3D12DepthStencilView::Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_DEPTH_STENCIL_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = {};
|
||||
device->CreateDepthStencilView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12DepthStencilView::InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_DEPTH_STENCIL_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = handle;
|
||||
device->CreateDepthStencilView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12DepthStencilView::Shutdown() {
|
||||
m_handle = {};
|
||||
m_resource = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
62
engine/src/RHI/D3D12/D3D12DescriptorHeap.cpp
Normal file
62
engine/src/RHI/D3D12/D3D12DescriptorHeap.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12DescriptorHeap::D3D12DescriptorHeap()
|
||||
: m_type(DescriptorHeapType::CBV_SRV_UAV)
|
||||
, m_numDescriptors(0)
|
||||
, m_descriptorSize(0)
|
||||
, m_shaderVisible(false) {
|
||||
}
|
||||
|
||||
D3D12DescriptorHeap::~D3D12DescriptorHeap() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12DescriptorHeap::Initialize(ID3D12Device* device, DescriptorHeapType type, uint32_t numDescriptors, bool shaderVisible) {
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = ToD3D12(type);
|
||||
desc.NumDescriptors = numDescriptors;
|
||||
desc.Flags = shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
desc.NodeMask = 0;
|
||||
|
||||
HRESULT hResult = device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_descriptorHeap));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
m_numDescriptors = numDescriptors;
|
||||
m_shaderVisible = shaderVisible;
|
||||
m_descriptorSize = device->GetDescriptorHandleIncrementSize(ToD3D12(type));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12DescriptorHeap::Shutdown() {
|
||||
m_descriptorHeap.Reset();
|
||||
}
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index) const {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
handle.ptr += index * m_descriptorSize;
|
||||
return handle;
|
||||
}
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandle(uint32_t index) const {
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
||||
handle.ptr += index * m_descriptorSize;
|
||||
return handle;
|
||||
}
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart() const {
|
||||
return m_descriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
}
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart() const {
|
||||
return m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
173
engine/src/RHI/D3D12/D3D12Device.cpp
Normal file
173
engine/src/RHI/D3D12/D3D12Device.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
QueryDeviceInfo();
|
||||
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;
|
||||
|
||||
{
|
||||
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) {
|
||||
OutputDebugStringA("[DEBUG] CreateDevice: start\n");
|
||||
HRESULT hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device));
|
||||
if (FAILED(hr)) {
|
||||
char buf[256];
|
||||
sprintf(buf, "[DEBUG] CreateDevice: D3D12CreateDevice failed! hr=%08X\n", hr);
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void D3D12Device::QueryDeviceInfo() {
|
||||
if (!m_adapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
m_adapter->GetDesc1(&desc);
|
||||
|
||||
m_deviceInfo.vendorId = desc.VendorId;
|
||||
m_deviceInfo.deviceId = desc.DeviceId;
|
||||
m_deviceInfo.dedicatedVideoMemory = desc.DedicatedVideoMemory;
|
||||
m_deviceInfo.dedicatedSystemMemory = desc.DedicatedSystemMemory;
|
||||
m_deviceInfo.sharedSystemMemory = desc.SharedSystemMemory;
|
||||
m_deviceInfo.deviceName = desc.Description;
|
||||
|
||||
m_deviceInfo.supportsRaytracing = false;
|
||||
m_deviceInfo.supportsMeshShaders = false;
|
||||
m_deviceInfo.supportsSamplerFeedback = false;
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5 = {};
|
||||
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5)))) {
|
||||
m_deviceInfo.supportsRaytracing = (options5.RaytracingTier != D3D12_RAYTRACING_TIER_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7 = {};
|
||||
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)))) {
|
||||
m_deviceInfo.supportsSamplerFeedback = (options7.SamplerFeedbackTier != D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED);
|
||||
m_deviceInfo.supportsMeshShaders = (options7.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
UINT D3D12Device::GetDescriptorHandleIncrementSize(DescriptorHeapType type) const {
|
||||
return m_device->GetDescriptorHandleIncrementSize(ToD3D12(type));
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
52
engine/src/RHI/D3D12/D3D12Fence.cpp
Normal file
52
engine/src/RHI/D3D12/D3D12Fence.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Fence.h"
|
||||
#include <Windows.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12Fence::D3D12Fence()
|
||||
: m_eventHandle(nullptr) {
|
||||
}
|
||||
|
||||
D3D12Fence::~D3D12Fence() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12Fence::Initialize(ID3D12Device* device, uint64_t initialValue) {
|
||||
HRESULT hResult = device->CreateFence(
|
||||
initialValue,
|
||||
D3D12_FENCE_FLAG_NONE,
|
||||
IID_PPV_ARGS(&m_fence));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
return m_eventHandle != nullptr;
|
||||
}
|
||||
|
||||
void D3D12Fence::Shutdown() {
|
||||
if (m_eventHandle) {
|
||||
CloseHandle(m_eventHandle);
|
||||
m_eventHandle = nullptr;
|
||||
}
|
||||
m_fence.Reset();
|
||||
}
|
||||
|
||||
void D3D12Fence::Signal(uint64_t value) {
|
||||
m_fence->Signal(value);
|
||||
}
|
||||
|
||||
void D3D12Fence::Wait(uint64_t value) {
|
||||
if (m_fence->GetCompletedValue() < value) {
|
||||
m_fence->SetEventOnCompletion(value, m_eventHandle);
|
||||
WaitForSingleObject(m_eventHandle, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t D3D12Fence::GetCompletedValue() {
|
||||
return m_fence->GetCompletedValue();
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
26
engine/src/RHI/D3D12/D3D12PipelineState.cpp
Normal file
26
engine/src/RHI/D3D12/D3D12PipelineState.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12PipelineState::D3D12PipelineState() {
|
||||
}
|
||||
|
||||
D3D12PipelineState::~D3D12PipelineState() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12PipelineState::Initialize(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc) {
|
||||
HRESULT hResult = device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&m_pipelineState));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12PipelineState::Shutdown() {
|
||||
m_pipelineState.Reset();
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
50
engine/src/RHI/D3D12/D3D12QueryHeap.cpp
Normal file
50
engine/src/RHI/D3D12/D3D12QueryHeap.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12QueryHeap.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12QueryHeap::D3D12QueryHeap()
|
||||
: m_type(QueryType::Timestamp)
|
||||
, m_count(0) {
|
||||
}
|
||||
|
||||
D3D12QueryHeap::~D3D12QueryHeap() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12QueryHeap::Initialize(ID3D12Device* device, QueryType type, uint32_t count) {
|
||||
D3D12_QUERY_HEAP_DESC desc = {};
|
||||
desc.Count = count;
|
||||
desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
desc.NodeMask = 0;
|
||||
|
||||
switch (type) {
|
||||
case QueryType::Timestamp:
|
||||
desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
break;
|
||||
case QueryType::Occlusion:
|
||||
desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
|
||||
break;
|
||||
case QueryType::PipelineStatistics:
|
||||
desc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
|
||||
break;
|
||||
}
|
||||
|
||||
HRESULT hResult = device->CreateQueryHeap(&desc, IID_PPV_ARGS(&m_queryHeap));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
m_count = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12QueryHeap::Shutdown() {
|
||||
m_queryHeap.Reset();
|
||||
m_type = QueryType::Timestamp;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
33
engine/src/RHI/D3D12/D3D12RenderTargetView.cpp
Normal file
33
engine/src/RHI/D3D12/D3D12RenderTargetView.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12RenderTargetView::D3D12RenderTargetView()
|
||||
: m_handle({0})
|
||||
, m_resource(nullptr) {
|
||||
}
|
||||
|
||||
D3D12RenderTargetView::~D3D12RenderTargetView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void D3D12RenderTargetView::Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_RENDER_TARGET_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = {};
|
||||
device->CreateRenderTargetView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12RenderTargetView::InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_RENDER_TARGET_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = handle;
|
||||
device->CreateRenderTargetView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12RenderTargetView::Shutdown() {
|
||||
m_handle = {};
|
||||
m_resource = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
41
engine/src/RHI/D3D12/D3D12RootSignature.cpp
Normal file
41
engine/src/RHI/D3D12/D3D12RootSignature.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12RootSignature.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12RootSignature::D3D12RootSignature() {
|
||||
}
|
||||
|
||||
D3D12RootSignature::~D3D12RootSignature() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12RootSignature::Initialize(ID3D12Device* device, const D3D12_ROOT_SIGNATURE_DESC& desc) {
|
||||
ID3DBlob* signature = nullptr;
|
||||
ID3DBlob* error = nullptr;
|
||||
|
||||
HRESULT hResult = D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
|
||||
if (FAILED(hResult)) {
|
||||
if (error) {
|
||||
error->Release();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hResult = device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature));
|
||||
|
||||
signature->Release();
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12RootSignature::Shutdown() {
|
||||
m_rootSignature.Reset();
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
24
engine/src/RHI/D3D12/D3D12Sampler.cpp
Normal file
24
engine/src/RHI/D3D12/D3D12Sampler.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12Sampler::D3D12Sampler() {
|
||||
memset(&m_desc, 0, sizeof(D3D12_SAMPLER_DESC));
|
||||
}
|
||||
|
||||
D3D12Sampler::~D3D12Sampler() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12Sampler::Initialize(ID3D12Device* device, const D3D12_SAMPLER_DESC& desc) {
|
||||
m_desc = desc;
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12Sampler::Shutdown() {
|
||||
memset(&m_desc, 0, sizeof(D3D12_SAMPLER_DESC));
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
168
engine/src/RHI/D3D12/D3D12Screenshot.cpp
Normal file
168
engine/src/RHI/D3D12/D3D12Screenshot.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "RHI/D3D12/D3D12Screenshot.h"
|
||||
#include "Debug/Logger.h"
|
||||
#include <d3d12.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
bool D3D12Screenshot::Capture(ID3D12Device* device,
|
||||
ID3D12CommandQueue* commandQueue,
|
||||
ID3D12Resource* renderTarget,
|
||||
const char* filename,
|
||||
uint32_t width,
|
||||
uint32_t height) {
|
||||
return CopyToReadbackAndSave(device, commandQueue, renderTarget, filename, width, height);
|
||||
}
|
||||
|
||||
bool D3D12Screenshot::CopyToReadbackAndSave(ID3D12Device* device,
|
||||
ID3D12CommandQueue* commandQueue,
|
||||
ID3D12Resource* renderTarget,
|
||||
const char* filename,
|
||||
uint32_t width,
|
||||
uint32_t height) {
|
||||
D3D12_RESOURCE_DESC rtDesc = renderTarget->GetDesc();
|
||||
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout = {};
|
||||
UINT64 totalSize = 0;
|
||||
device->GetCopyableFootprints(&rtDesc, 0, 1, 0, &layout, nullptr, nullptr, &totalSize);
|
||||
UINT rowPitch = layout.Footprint.RowPitch;
|
||||
|
||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||
HRESULT hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
heapProps.Type = D3D12_HEAP_TYPE_READBACK;
|
||||
D3D12_RESOURCE_DESC readbackDesc = {};
|
||||
readbackDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
readbackDesc.Alignment = 0;
|
||||
readbackDesc.Width = totalSize;
|
||||
readbackDesc.Height = 1;
|
||||
readbackDesc.DepthOrArraySize = 1;
|
||||
readbackDesc.MipLevels = 1;
|
||||
readbackDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
readbackDesc.SampleDesc.Count = 1;
|
||||
readbackDesc.SampleDesc.Quality = 0;
|
||||
readbackDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
readbackDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
ID3D12Resource* readbackBuffer = nullptr;
|
||||
hr = device->CreateCommittedResource(
|
||||
&heapProps,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&readbackDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&readbackBuffer));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
cmdAlloc->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* cmdList = nullptr;
|
||||
hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
||||
if (FAILED(hr)) {
|
||||
cmdAlloc->Release();
|
||||
readbackBuffer->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = renderTarget;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
cmdList->ResourceBarrier(1, &barrier);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
|
||||
srcLoc.pResource = renderTarget;
|
||||
srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
srcLoc.SubresourceIndex = 0;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstLoc = {};
|
||||
dstLoc.pResource = readbackBuffer;
|
||||
dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
dstLoc.PlacedFootprint = layout;
|
||||
|
||||
D3D12_BOX srcBox = {};
|
||||
srcBox.left = 0;
|
||||
srcBox.top = 0;
|
||||
srcBox.front = 0;
|
||||
srcBox.right = rtDesc.Width;
|
||||
srcBox.bottom = rtDesc.Height;
|
||||
srcBox.back = 1;
|
||||
cmdList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, &srcBox);
|
||||
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
cmdList->ResourceBarrier(1, &barrier);
|
||||
|
||||
cmdList->Close();
|
||||
ID3D12CommandList* ppCmdLists[] = { cmdList };
|
||||
commandQueue->ExecuteCommandLists(1, ppCmdLists);
|
||||
|
||||
HANDLE fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
ID3D12Fence* fence = nullptr;
|
||||
hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
if (SUCCEEDED(hr)) {
|
||||
UINT64 fenceValue = 1;
|
||||
commandQueue->Signal(fence, fenceValue);
|
||||
if (fence->GetCompletedValue() < fenceValue) {
|
||||
fence->SetEventOnCompletion(fenceValue, fenceEvent);
|
||||
WaitForSingleObject(fenceEvent, INFINITE);
|
||||
}
|
||||
fence->Release();
|
||||
}
|
||||
CloseHandle(fenceEvent);
|
||||
|
||||
D3D12_RANGE readRange = { 0, 0 };
|
||||
unsigned char* mappedData = nullptr;
|
||||
hr = readbackBuffer->Map(0, &readRange, (void**)&mappedData);
|
||||
if (FAILED(hr)) {
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
readbackBuffer->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
readbackBuffer->Unmap(0, nullptr);
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
readbackBuffer->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "P6\n%d %d\n255\n", width, height);
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
for (uint32_t x = 0; x < width; x++) {
|
||||
int idx = y * rowPitch + x * 4;
|
||||
unsigned char r = mappedData[idx + 0];
|
||||
unsigned char g = mappedData[idx + 1];
|
||||
unsigned char b = mappedData[idx + 2];
|
||||
fwrite(&r, 1, 1, fp);
|
||||
fwrite(&g, 1, 1, fp);
|
||||
fwrite(&b, 1, 1, fp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
D3D12_RANGE writeRange = { 0, 0 };
|
||||
readbackBuffer->Unmap(0, &writeRange);
|
||||
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
readbackBuffer->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
70
engine/src/RHI/D3D12/D3D12Shader.cpp
Normal file
70
engine/src/RHI/D3D12/D3D12Shader.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12Shader::D3D12Shader()
|
||||
: m_type(ShaderType::Vertex) {
|
||||
}
|
||||
|
||||
D3D12Shader::~D3D12Shader() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12Shader::CompileFromFile(const wchar_t* filePath, const char* entryPoint, const char* target) {
|
||||
HRESULT hResult = D3DCompileFromFile(filePath, nullptr, nullptr, entryPoint, target,
|
||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &m_bytecode, &m_error);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
if (m_error) {
|
||||
const char* errorMsg = static_cast<const char*>(m_error->GetBufferPointer());
|
||||
OutputDebugStringA(errorMsg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strstr(target, "vs_")) {
|
||||
m_type = ShaderType::Vertex;
|
||||
} else if (strstr(target, "ps_")) {
|
||||
m_type = ShaderType::Pixel;
|
||||
} else if (strstr(target, "gs_")) {
|
||||
m_type = ShaderType::Geometry;
|
||||
} else if (strstr(target, "cs_")) {
|
||||
m_type = ShaderType::Compute;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Shader::Compile(const void* sourceData, size_t sourceSize, const char* entryPoint, const char* target) {
|
||||
HRESULT hResult = D3DCompile(sourceData, sourceSize, nullptr, nullptr, nullptr, entryPoint, target,
|
||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &m_bytecode, &m_error);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
if (m_error) {
|
||||
const char* errorMsg = static_cast<const char*>(m_error->GetBufferPointer());
|
||||
OutputDebugStringA(errorMsg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12Shader::Shutdown() {
|
||||
m_bytecode.Reset();
|
||||
m_error.Reset();
|
||||
}
|
||||
|
||||
const D3D12_SHADER_BYTECODE D3D12Shader::GetBytecode() const {
|
||||
D3D12_SHADER_BYTECODE bytecode = {};
|
||||
if (m_bytecode) {
|
||||
bytecode.pShaderBytecode = m_bytecode->GetBufferPointer();
|
||||
bytecode.BytecodeLength = m_bytecode->GetBufferSize();
|
||||
}
|
||||
return bytecode;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
33
engine/src/RHI/D3D12/D3D12ShaderResourceView.cpp
Normal file
33
engine/src/RHI/D3D12/D3D12ShaderResourceView.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12ShaderResourceView::D3D12ShaderResourceView()
|
||||
: m_handle({0})
|
||||
, m_resource(nullptr) {
|
||||
}
|
||||
|
||||
D3D12ShaderResourceView::~D3D12ShaderResourceView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void D3D12ShaderResourceView::Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_SHADER_RESOURCE_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = {};
|
||||
device->CreateShaderResourceView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12ShaderResourceView::InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_SHADER_RESOURCE_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = handle;
|
||||
device->CreateShaderResourceView(resource, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12ShaderResourceView::Shutdown() {
|
||||
m_handle = {};
|
||||
m_resource = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
87
engine/src/RHI/D3D12/D3D12SwapChain.cpp
Normal file
87
engine/src/RHI/D3D12/D3D12SwapChain.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12SwapChain.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12SwapChain::D3D12SwapChain()
|
||||
: m_windowHandle(nullptr)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_bufferCount(2) {
|
||||
}
|
||||
|
||||
D3D12SwapChain::~D3D12SwapChain() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12SwapChain::Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* commandQueue, HWND windowHandle, uint32_t width, uint32_t height, uint32_t bufferCount) {
|
||||
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
|
||||
swapChainDesc.BufferCount = bufferCount;
|
||||
swapChainDesc.BufferDesc.Width = width;
|
||||
swapChainDesc.BufferDesc.Height = height;
|
||||
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.OutputWindow = windowHandle;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Windowed = TRUE;
|
||||
|
||||
IDXGISwapChain* swapChain = nullptr;
|
||||
HRESULT hResult = factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain);
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hResult = swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_commandQueue = commandQueue;
|
||||
m_windowHandle = windowHandle;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_bufferCount = bufferCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height) {
|
||||
HRESULT hResult = swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12SwapChain::Shutdown() {
|
||||
m_swapChain.Reset();
|
||||
}
|
||||
|
||||
uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const {
|
||||
return m_swapChain->GetCurrentBackBufferIndex();
|
||||
}
|
||||
|
||||
ID3D12Resource* D3D12SwapChain::GetBackBuffer(uint32_t index) const {
|
||||
ID3D12Resource* resource = nullptr;
|
||||
m_swapChain->GetBuffer(index, IID_PPV_ARGS(&resource));
|
||||
return resource;
|
||||
}
|
||||
|
||||
void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) {
|
||||
m_swapChain->Present(syncInterval, flags);
|
||||
}
|
||||
|
||||
void D3D12SwapChain::Resize(uint32_t width, uint32_t height) {
|
||||
m_swapChain->ResizeBuffers(m_bufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
185
engine/src/RHI/D3D12/D3D12Texture.cpp
Normal file
185
engine/src/RHI/D3D12/D3D12Texture.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12Texture::D3D12Texture() {
|
||||
}
|
||||
|
||||
D3D12Texture::~D3D12Texture() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool D3D12Texture::Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& desc, D3D12_RESOURCE_STATES initialState) {
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
heapProperties.CreationNodeMask = 0;
|
||||
heapProperties.VisibleNodeMask = 0;
|
||||
|
||||
D3D12_CLEAR_VALUE* pOptimizedClearValue = nullptr;
|
||||
|
||||
HRESULT hResult = device->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
initialState,
|
||||
pOptimizedClearValue,
|
||||
IID_PPV_ARGS(&m_resource)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::InitializeFromExisting(ID3D12Resource* resource) {
|
||||
m_resource = resource;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList,
|
||||
const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format) {
|
||||
|
||||
D3D12_RESOURCE_DESC textureDesc = {};
|
||||
textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
textureDesc.Alignment = 0;
|
||||
textureDesc.Width = width;
|
||||
textureDesc.Height = height;
|
||||
textureDesc.DepthOrArraySize = 1;
|
||||
textureDesc.MipLevels = 1;
|
||||
textureDesc.Format = format;
|
||||
textureDesc.SampleDesc.Count = 1;
|
||||
textureDesc.SampleDesc.Quality = 0;
|
||||
textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
HRESULT hResult = device->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&textureDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_resource)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
textureDesc = m_resource->GetDesc();
|
||||
UINT64 memorySizeUsed = 0;
|
||||
UINT64 rowSizeInBytes = 0;
|
||||
UINT rowUsed = 0;
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT subresourceFootprint;
|
||||
device->GetCopyableFootprints(&textureDesc, 0, 1, 0,
|
||||
&subresourceFootprint, &rowUsed, &rowSizeInBytes, &memorySizeUsed);
|
||||
|
||||
ID3D12Resource* tempBufferObject = nullptr;
|
||||
D3D12_HEAP_PROPERTIES d3dTempHeapProperties = {};
|
||||
d3dTempHeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
|
||||
D3D12_RESOURCE_DESC d3d12TempResourceDesc = {};
|
||||
d3d12TempResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
d3d12TempResourceDesc.Alignment = 0;
|
||||
d3d12TempResourceDesc.Width = memorySizeUsed;
|
||||
d3d12TempResourceDesc.Height = 1;
|
||||
d3d12TempResourceDesc.DepthOrArraySize = 1;
|
||||
d3d12TempResourceDesc.MipLevels = 1;
|
||||
d3d12TempResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
d3d12TempResourceDesc.SampleDesc.Count = 1;
|
||||
d3d12TempResourceDesc.SampleDesc.Quality = 0;
|
||||
d3d12TempResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
d3d12TempResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
hResult = device->CreateCommittedResource(
|
||||
&d3dTempHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&d3d12TempResourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&tempBufferObject)
|
||||
);
|
||||
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE* pData;
|
||||
tempBufferObject->Map(0, nullptr, reinterpret_cast<void**>(&pData));
|
||||
BYTE* pDstTempBuffer = reinterpret_cast<BYTE*>(pData + subresourceFootprint.Offset);
|
||||
const BYTE* pSrcData = reinterpret_cast<const BYTE*>(pixelData);
|
||||
for (UINT i = 0; i < rowUsed; i++) {
|
||||
memcpy(pDstTempBuffer + subresourceFootprint.Footprint.RowPitch * i, pSrcData + rowSizeInBytes * i, rowSizeInBytes);
|
||||
}
|
||||
tempBufferObject->Unmap(0, nullptr);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dst = {};
|
||||
dst.pResource = m_resource.Get();
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = 0;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION src = {};
|
||||
src.pResource = tempBufferObject;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint = subresourceFootprint;
|
||||
commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = m_resource.Get();
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12Texture::InitializeDepthStencil(ID3D12Device* device, uint32_t width, uint32_t height, DXGI_FORMAT format) {
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProperties = {};
|
||||
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12_CLEAR_VALUE clearValue = {};
|
||||
clearValue.Format = format;
|
||||
clearValue.DepthStencil.Depth = 1.0f;
|
||||
clearValue.DepthStencil.Stencil = 0;
|
||||
|
||||
HRESULT hResult = device->CreateCommittedResource(
|
||||
&heapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
||||
&clearValue,
|
||||
IID_PPV_ARGS(&m_resource)
|
||||
);
|
||||
|
||||
return SUCCEEDED(hResult);
|
||||
}
|
||||
|
||||
void D3D12Texture::Shutdown() {
|
||||
m_resource.Reset();
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
27
engine/src/RHI/D3D12/D3D12UnorderedAccessView.cpp
Normal file
27
engine/src/RHI/D3D12/D3D12UnorderedAccessView.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
D3D12UnorderedAccessView::D3D12UnorderedAccessView()
|
||||
: m_handle({0})
|
||||
, m_resource(nullptr) {
|
||||
}
|
||||
|
||||
D3D12UnorderedAccessView::~D3D12UnorderedAccessView() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void D3D12UnorderedAccessView::Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC* desc) {
|
||||
m_resource = resource;
|
||||
m_handle = {};
|
||||
device->CreateUnorderedAccessView(resource, nullptr, desc, m_handle);
|
||||
}
|
||||
|
||||
void D3D12UnorderedAccessView::Shutdown() {
|
||||
m_handle = {};
|
||||
m_resource = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user