#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h" #include "XCEngine/RHI/D3D12/D3D12CommandList.h" #include "XCEngine/RHI/D3D12/D3D12Fence.h" #include 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, void** lists) { ExecuteCommandListsInternal(count, reinterpret_cast(lists)); } void D3D12CommandQueue::ExecuteCommandListsInternal(uint32_t count, ID3D12CommandList** lists) { m_commandQueue->ExecuteCommandLists(count, lists); } void D3D12CommandQueue::Signal(RHIFence* fence, uint64_t value) { if (fence) { m_commandQueue->Signal(static_cast(fence)->GetFence(), value); } } void D3D12CommandQueue::Signal(ID3D12Fence* fence, uint64_t value) { if (fence) { m_commandQueue->Signal(fence, value); } } void D3D12CommandQueue::Wait(RHIFence* fence, uint64_t value) { if (fence) { m_commandQueue->Wait(static_cast(fence)->GetFence(), value); } } void D3D12CommandQueue::Wait(ID3D12Fence* fence, uint64_t value) { if (fence) { m_commandQueue->Wait(fence, value); } } uint64_t D3D12CommandQueue::GetCompletedValue() { return 0; } void D3D12CommandQueue::WaitForIdle() { // Get the device from the command queue ID3D12Device* device = nullptr; HRESULT hr = m_commandQueue->GetDevice(IID_PPV_ARGS(&device)); if (SUCCEEDED(hr)) { // Create a fence to signal when queue is idle ID3D12Fence* fence = nullptr; hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); if (SUCCEEDED(hr)) { // Signal the fence m_commandQueue->Signal(fence, 1); // Wait for it to complete while (fence->GetCompletedValue() < 1) { Sleep(1); } fence->Release(); } device->Release(); } } } // namespace RHI } // namespace XCEngine