- Remove unnecessary inline keywords from RHICommandList - Add TextureType enum for proper texture type classification - Update DescriptorSet API to support binding with pipeline layout - Simplify D3D12CommandList implementation - Implement descriptor set binding with pipeline layout for both D3D12 and OpenGL
652 lines
26 KiB
C++
652 lines
26 KiB
C++
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12RenderPass.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorSet.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)
|
|
, m_currentShader(nullptr)
|
|
, m_currentPipelineLayout(nullptr) {
|
|
}
|
|
|
|
D3D12CommandList::~D3D12CommandList() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool D3D12CommandList::Initialize(ID3D12Device* device, CommandQueueType type, ID3D12CommandAllocator* allocator) {
|
|
D3D12_COMMAND_LIST_TYPE listType = ToD3D12(type);
|
|
|
|
m_commandAllocator = allocator;
|
|
m_device = device;
|
|
|
|
char buf[512];
|
|
sprintf(buf, "[D3D12CommandList::Initialize] device=%p, allocator=%p, type=%d\n", device, allocator, (int)type);
|
|
OutputDebugStringA(buf);
|
|
|
|
HRESULT hResult = device->CreateCommandList(
|
|
0,
|
|
listType,
|
|
allocator,
|
|
nullptr,
|
|
IID_PPV_ARGS(&m_commandList)
|
|
);
|
|
|
|
if (FAILED(hResult)) {
|
|
sprintf(buf, "[D3D12CommandList::Initialize] CreateCommandList failed: hr=0x%08X\n", hResult);
|
|
OutputDebugStringA(buf);
|
|
return false;
|
|
}
|
|
|
|
m_type = type;
|
|
|
|
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
|
|
heapDesc.NumDescriptors = 16;
|
|
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
|
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
|
heapDesc.NodeMask = 0;
|
|
hResult = device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_rtvHeap));
|
|
if (FAILED(hResult)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void D3D12CommandList::Shutdown() {
|
|
m_commandList.Reset();
|
|
m_rtvHeap.Reset();
|
|
m_resourceStateMap.clear();
|
|
m_trackedResources.clear();
|
|
m_currentShader = nullptr;
|
|
}
|
|
|
|
void D3D12CommandList::Reset() {
|
|
if (m_commandList && m_commandAllocator) {
|
|
m_commandList->Reset(m_commandAllocator.Get(), nullptr);
|
|
}
|
|
m_currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
|
m_currentPipelineState = nullptr;
|
|
m_currentRootSignature = nullptr;
|
|
m_currentPipelineLayout = nullptr;
|
|
m_currentDescriptorHeap = nullptr;
|
|
m_resourceStateMap.clear();
|
|
m_trackedResources.clear();
|
|
m_boundRenderTargets.clear();
|
|
m_depthStencilBound = false;
|
|
}
|
|
|
|
void D3D12CommandList::Close() {
|
|
m_commandList->Close();
|
|
}
|
|
|
|
void D3D12CommandList::SetShader(RHIShader* shader) {
|
|
m_currentShader = static_cast<D3D12Shader*>(shader);
|
|
}
|
|
|
|
void D3D12CommandList::SetPipelineLayout(D3D12PipelineLayout* layout) {
|
|
m_currentPipelineLayout = layout;
|
|
if (layout) {
|
|
SetRootSignature(layout->GetRootSignature());
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
|
if (!resource || !resource->IsValid()) return;
|
|
D3D12ResourceView* d3d12View = static_cast<D3D12ResourceView*>(resource);
|
|
TransitionBarrierInternal(d3d12View->GetResource(), stateBefore, stateAfter);
|
|
}
|
|
|
|
void D3D12CommandList::TransitionBarrier(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
|
if (!resource) return;
|
|
TransitionBarrierInternal(resource, stateBefore, stateAfter);
|
|
}
|
|
|
|
void D3D12CommandList::UAVBarrier(ID3D12Resource* resource) {
|
|
UAVBarrierInternal(resource);
|
|
}
|
|
|
|
void D3D12CommandList::AliasBarrier(ID3D12Resource* beforeResource, ID3D12Resource* afterResource) {
|
|
AliasBarrierInternal(beforeResource, afterResource);
|
|
}
|
|
|
|
void D3D12CommandList::SetPipelineState(RHIPipelineState* pso) {
|
|
if (!pso) return;
|
|
|
|
if (pso->GetType() == PipelineType::Compute) {
|
|
D3D12PipelineState* d3d12Pso = static_cast<D3D12PipelineState*>(pso);
|
|
SetPipelineStateInternal(d3d12Pso->GetComputePipelineState());
|
|
} else {
|
|
SetPipelineStateInternal(static_cast<ID3D12PipelineState*>(pso->GetNativeHandle()));
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::SetPipelineState(ID3D12PipelineState* pso) {
|
|
SetPipelineStateInternal(pso);
|
|
}
|
|
|
|
void D3D12CommandList::SetGraphicsDescriptorSets(
|
|
uint32_t firstSet,
|
|
uint32_t count,
|
|
RHIDescriptorSet** descriptorSets,
|
|
RHIPipelineLayout* pipelineLayout) {
|
|
if (pipelineLayout == nullptr || descriptorSets == nullptr) {
|
|
return;
|
|
}
|
|
|
|
D3D12PipelineLayout* d3d12Layout = static_cast<D3D12PipelineLayout*>(pipelineLayout);
|
|
SetPipelineLayout(d3d12Layout);
|
|
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
if (descriptorSets[i] == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
D3D12DescriptorSet* d3d12Set = static_cast<D3D12DescriptorSet*>(descriptorSets[i]);
|
|
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = d3d12Set->GetGPUHandle();
|
|
|
|
uint32_t rootIndex = firstSet + i;
|
|
SetGraphicsRootDescriptorTable(rootIndex, gpuHandle);
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::SetComputeDescriptorSets(
|
|
uint32_t firstSet,
|
|
uint32_t count,
|
|
RHIDescriptorSet** descriptorSets,
|
|
RHIPipelineLayout* pipelineLayout) {
|
|
if (pipelineLayout == nullptr || descriptorSets == nullptr) {
|
|
return;
|
|
}
|
|
|
|
D3D12PipelineLayout* d3d12Layout = static_cast<D3D12PipelineLayout*>(pipelineLayout);
|
|
SetPipelineLayout(d3d12Layout);
|
|
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
if (descriptorSets[i] == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
D3D12DescriptorSet* d3d12Set = static_cast<D3D12DescriptorSet*>(descriptorSets[i]);
|
|
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = d3d12Set->GetGPUHandle();
|
|
|
|
uint32_t rootIndex = firstSet + i;
|
|
m_commandList->SetComputeRootDescriptorTable(rootIndex, gpuHandle);
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::TransitionBarrierInternal(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::UAVBarrierInternal(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::AliasBarrierInternal(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::BeginRenderPass(RHIRenderPass* renderPass, RHIFramebuffer* framebuffer,
|
|
const Rect& renderArea, uint32_t clearValueCount, const ClearValue* clearValues) {
|
|
if (!framebuffer || !renderPass) return;
|
|
|
|
D3D12_VIEWPORT d3dViewport = {};
|
|
d3dViewport.TopLeftX = static_cast<float>(renderArea.left);
|
|
d3dViewport.TopLeftY = static_cast<float>(renderArea.top);
|
|
d3dViewport.Width = static_cast<float>(renderArea.right - renderArea.left);
|
|
d3dViewport.Height = static_cast<float>(renderArea.bottom - renderArea.top);
|
|
d3dViewport.MinDepth = 0.0f;
|
|
d3dViewport.MaxDepth = 1.0f;
|
|
m_commandList->RSSetViewports(1, &d3dViewport);
|
|
|
|
D3D12_RECT d3dScissor = {};
|
|
d3dScissor.left = renderArea.left;
|
|
d3dScissor.top = renderArea.top;
|
|
d3dScissor.right = renderArea.right;
|
|
d3dScissor.bottom = renderArea.bottom;
|
|
m_commandList->RSSetScissorRects(1, &d3dScissor);
|
|
|
|
D3D12Framebuffer* d3d12Framebuffer = static_cast<D3D12Framebuffer*>(framebuffer);
|
|
|
|
uint32_t rtCount = d3d12Framebuffer->GetRenderTargetCount();
|
|
const D3D12_CPU_DESCRIPTOR_HANDLE* rtHandles = d3d12Framebuffer->GetRenderTargetHandles();
|
|
bool hasDS = d3d12Framebuffer->HasDepthStencil();
|
|
D3D12_CPU_DESCRIPTOR_HANDLE dsHandle = d3d12Framebuffer->GetDepthStencilHandle();
|
|
|
|
D3D12RenderPass* d3d12RenderPass = static_cast<D3D12RenderPass*>(renderPass);
|
|
const AttachmentDesc* attachments = d3d12RenderPass->GetColorAttachments();
|
|
|
|
for (uint32_t i = 0; i < rtCount; ++i) {
|
|
if (attachments[i].loadOp == LoadAction::Clear && clearValueCount > i) {
|
|
m_commandList->ClearRenderTargetView(rtHandles[i], &clearValues[i].color.r, 0, nullptr);
|
|
}
|
|
}
|
|
|
|
if (hasDS) {
|
|
const AttachmentDesc* dsAttachment = d3d12RenderPass->GetDepthStencilAttachment();
|
|
if (dsAttachment) {
|
|
uint32_t clearFlags = 0;
|
|
if (dsAttachment->loadOp == LoadAction::Clear) clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
|
|
if (dsAttachment->stencilLoadOp == LoadAction::Clear) clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
|
if (clearFlags && clearValueCount > rtCount) {
|
|
m_commandList->ClearDepthStencilView(dsHandle, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), clearValues[rtCount].depth, clearValues[rtCount].stencil, 0, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_commandList->OMSetRenderTargets(rtCount, rtHandles, FALSE, hasDS ? &dsHandle : nullptr);
|
|
|
|
m_boundRenderTargets.clear();
|
|
for (uint32_t i = 0; i < rtCount; ++i) {
|
|
m_boundRenderTargets.push_back(rtHandles[i]);
|
|
}
|
|
m_boundDepthStencil = dsHandle;
|
|
m_depthStencilBound = hasDS;
|
|
}
|
|
|
|
void D3D12CommandList::EndRenderPass() {
|
|
}
|
|
|
|
void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
|
m_commandList->SetPipelineState(pso);
|
|
m_currentPipelineState = pso;
|
|
if (m_currentRootSignature) {
|
|
m_commandList->SetGraphicsRootSignature(m_currentRootSignature);
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::SetRootSignature(ID3D12RootSignature* signature) {
|
|
m_commandList->SetGraphicsRootSignature(signature);
|
|
m_currentRootSignature = signature;
|
|
}
|
|
|
|
void D3D12CommandList::SetBlendFactor(const float blendFactor[4]) {
|
|
m_commandList->OMSetBlendFactor(blendFactor);
|
|
}
|
|
|
|
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, RHIResourceView** renderTargets, RHIResourceView* depthStencil) {
|
|
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> rtvHandles(count);
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
if (renderTargets[i] && renderTargets[i]->IsValid()) {
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(renderTargets[i]);
|
|
rtvHandles[i] = view->GetCPUHandle();
|
|
}
|
|
}
|
|
|
|
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {};
|
|
if (depthStencil && depthStencil->IsValid()) {
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(depthStencil);
|
|
dsvHandle = view->GetCPUHandle();
|
|
}
|
|
|
|
m_commandList->OMSetRenderTargets(count, count > 0 ? rtvHandles.data() : nullptr, FALSE, depthStencil ? &dsvHandle : nullptr);
|
|
|
|
m_boundRenderTargets = rtvHandles;
|
|
if (depthStencil) {
|
|
m_boundDepthStencil = dsvHandle;
|
|
m_depthStencilBound = true;
|
|
} else {
|
|
m_depthStencilBound = false;
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::SetRenderTargetsInternal(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::SetRenderTargetsHandle(uint32_t count, const D3D12_CPU_DESCRIPTOR_HANDLE* renderTargetHandles, const D3D12_CPU_DESCRIPTOR_HANDLE* depthStencilHandle) {
|
|
m_commandList->OMSetRenderTargets(count, renderTargetHandles, FALSE, depthStencilHandle);
|
|
|
|
m_boundRenderTargets.clear();
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
m_boundRenderTargets.push_back(renderTargetHandles[i]);
|
|
}
|
|
|
|
if (depthStencilHandle) {
|
|
m_boundDepthStencil = *depthStencilHandle;
|
|
m_depthStencilBound = true;
|
|
} else {
|
|
m_depthStencilBound = false;
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) {
|
|
std::vector<D3D12_VERTEX_BUFFER_VIEW> views(count);
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
if (buffers[i] && buffers[i]->IsValid()) {
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffers[i]);
|
|
views[i].BufferLocation = view->GetResource()->GetGPUVirtualAddress() + offsets[i];
|
|
views[i].StrideInBytes = strides[i];
|
|
views[i].SizeInBytes = static_cast<UINT>(view->GetResource()->GetDesc().Width) - static_cast<UINT>(offsets[i]);
|
|
}
|
|
}
|
|
SetVertexBuffersInternal(startSlot, count, views.data());
|
|
}
|
|
|
|
void D3D12CommandList::SetVertexBuffersInternal(uint32_t startSlot, uint32_t count, const D3D12_VERTEX_BUFFER_VIEW* views) {
|
|
m_commandList->IASetVertexBuffers(startSlot, count, views);
|
|
}
|
|
|
|
void D3D12CommandList::SetVertexBuffer(uint32_t slot, ID3D12Resource* resource, uint64_t offset, uint32_t stride) {
|
|
D3D12_VERTEX_BUFFER_VIEW view = {};
|
|
view.BufferLocation = resource->GetGPUVirtualAddress() + offset;
|
|
view.SizeInBytes = static_cast<UINT>(resource->GetDesc().Width) - static_cast<UINT>(offset);
|
|
view.StrideInBytes = stride;
|
|
SetVertexBuffersInternal(slot, 1, &view);
|
|
}
|
|
|
|
void D3D12CommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset) {
|
|
if (!buffer || !buffer->IsValid()) return;
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffer);
|
|
SetIndexBufferInternal(view->GetResource(), offset, Format::R32_UInt);
|
|
}
|
|
|
|
void D3D12CommandList::SetIndexBuffer(ID3D12Resource* buffer, uint64_t offset, Format format) {
|
|
SetIndexBufferInternal(buffer, offset, format);
|
|
}
|
|
|
|
void D3D12CommandList::SetIndexBufferInternal(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(uint8_t stencilRef) {
|
|
m_commandList->OMSetStencilRef(stencilRef);
|
|
}
|
|
|
|
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) {
|
|
DrawInstancedIndirectInternal(argBuffer, alignedByteOffset);
|
|
}
|
|
|
|
void D3D12CommandList::DrawIndexedInstancedIndirect(ID3D12Resource* argBuffer, uint64_t alignedByteOffset) {
|
|
DrawIndexedInstancedIndirectInternal(argBuffer, alignedByteOffset);
|
|
}
|
|
|
|
void D3D12CommandList::DrawInstancedIndirectInternal(ID3D12Resource* argBuffer, uint64_t alignedByteOffset) {
|
|
m_commandList->ExecuteIndirect(nullptr, 1, argBuffer, alignedByteOffset, nullptr, 0);
|
|
}
|
|
|
|
void D3D12CommandList::DrawIndexedInstancedIndirectInternal(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) {
|
|
for (const auto& rtvHandle : m_boundRenderTargets) {
|
|
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::Clear(float r, float g, float b, float a, uint32_t buffers) {
|
|
float color[4] = { r, g, b, a };
|
|
if (buffers & 1) {
|
|
for (const auto& rtvHandle : m_boundRenderTargets) {
|
|
m_commandList->ClearRenderTargetView(rtvHandle, color, 0, nullptr);
|
|
}
|
|
}
|
|
if (buffers & 2 || buffers & 4) {
|
|
if (m_depthStencilBound) {
|
|
uint32_t clearFlags = 0;
|
|
if (buffers & 2) clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
|
|
if (buffers & 4) clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
|
|
m_commandList->ClearDepthStencilView(m_boundDepthStencil, static_cast<D3D12_CLEAR_FLAGS>(clearFlags), 1.0f, 0, 0, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void D3D12CommandList::ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) {
|
|
if (!renderTarget || !renderTarget->IsValid()) return;
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(renderTarget);
|
|
ClearRenderTargetView(view->GetCPUHandle(), color, 0, nullptr);
|
|
}
|
|
|
|
void D3D12CommandList::ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) {
|
|
if (!depthStencil || !depthStencil->IsValid()) return;
|
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(depthStencil);
|
|
ClearDepthStencilView(view->GetCPUHandle(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, depth, stencil, 0, nullptr);
|
|
}
|
|
|
|
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(RHIResourceView* dst, RHIResourceView* src) {
|
|
if (!dst || !src || !dst->IsValid() || !src->IsValid()) return;
|
|
D3D12ResourceView* dstView = static_cast<D3D12ResourceView*>(dst);
|
|
D3D12ResourceView* srcView = static_cast<D3D12ResourceView*>(src);
|
|
CopyResourceInternal(dstView->GetResource(), srcView->GetResource());
|
|
}
|
|
|
|
void D3D12CommandList::CopyResourceInternal(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) {
|
|
DispatchIndirectInternal(argBuffer, alignedByteOffset);
|
|
}
|
|
|
|
void D3D12CommandList::DispatchIndirectInternal(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
|