Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
cursey committed Apr 15, 2024
1 parent 7d15918 commit f83ecd5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 50 deletions.
51 changes: 25 additions & 26 deletions src/D3D12CommandContext.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
#include "D3D12CommandContext.hpp"

namespace d3d12 {
CommandContext::CommandContext(ID3D12Device* device, const wchar_t* name) {
D3D12CommandContext::D3D12CommandContext(ID3D12Device* device, const wchar_t* name) {
std::scoped_lock _{m_mtx};

m_cmd_allocator.Reset();
m_cmd_list.Reset();
m_fence.Reset();

if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_cmd_allocator)))) {
throw std::runtime_error("Failed to create command allocator");
throw std::runtime_error{"Failed to create command allocator"};
}

m_cmd_allocator->SetName(name);

if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_cmd_allocator.Get(), nullptr, IID_PPV_ARGS(&m_cmd_list)))) {
throw std::runtime_error("Failed to create command list");
throw std::runtime_error{"Failed to create command list"};
}

m_cmd_list->SetName(name);

if (FAILED(device->CreateFence(m_fence_value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)))) {
throw std::runtime_error("Failed to create fence");
throw std::runtime_error{"Failed to create fence"};
}

m_fence->SetName(name);
m_fence_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);

m_fence_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
m_is_setup = true;
}

void CommandContext::reset() {
void D3D12CommandContext::reset() {
std::scoped_lock _{m_mtx};
wait(2000);

Expand All @@ -45,7 +44,7 @@ void CommandContext::reset() {
m_waiting_for_fence = false;
}

void CommandContext::wait(uint32_t ms) {
void D3D12CommandContext::wait(uint32_t ms) {
std::scoped_lock _{m_mtx};

if (m_fence_event && m_waiting_for_fence) {
Expand All @@ -55,33 +54,33 @@ void CommandContext::wait(uint32_t ms) {
m_waiting_for_fence = false;

if (FAILED(m_cmd_allocator->Reset())) {
throw std::runtime_error("Failed to reset command allocator");
throw std::runtime_error{"Failed to reset command allocator"};
}

if (FAILED(m_cmd_list->Reset(m_cmd_allocator.Get(), nullptr))) {
throw std::runtime_error("Failed to reset command list");
throw std::runtime_error{"Failed to reset command list"};
}

m_has_commands = false;
}
}

void CommandContext::execute(ID3D12CommandQueue* command_queue) {
std::scoped_lock _{m_mtx};
D3D12CommandContext::ComPtr<ID3D12GraphicsCommandList>& D3D12CommandContext::begin() {
m_mtx.lock();
wait(INFINITE);
return m_cmd_list;
}

if (m_has_commands) {
if (FAILED(m_cmd_list->Close())) {
throw std::runtime_error("Failed to close command list");
}
void D3D12CommandContext::end(ID3D12CommandQueue* command_queue) {
if (FAILED(m_cmd_list->Close())) {
throw std::runtime_error("Failed to close command list");
}

ID3D12CommandList* const cmd_lists[] = {m_cmd_list.Get()};
ID3D12CommandList* const cmd_lists[] = {m_cmd_list.Get()};

command_queue->ExecuteCommandLists(1, cmd_lists);
command_queue->Signal(m_fence.Get(), ++m_fence_value);
m_fence->SetEventOnCompletion(m_fence_value, m_fence_event);
command_queue->ExecuteCommandLists(1, cmd_lists);
command_queue->Signal(m_fence.Get(), ++m_fence_value);
m_fence->SetEventOnCompletion(m_fence_value, m_fence_event);

m_waiting_for_fence = true;
m_has_commands = false;
}
m_waiting_for_fence = true;

m_mtx.unlock();
}
} // namespace d3d12
21 changes: 7 additions & 14 deletions src/D3D12CommandContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,20 @@
#include <mutex>
#include <wrl.h>

namespace d3d12 {
struct TextureContext;

class CommandContext {
class D3D12CommandContext {
public:
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>;

CommandContext() = delete;
CommandContext(ID3D12Device* device, const wchar_t* name = L"REFD2D CommandContext object");
virtual ~CommandContext() { reset(); }
D3D12CommandContext() = delete;
D3D12CommandContext(ID3D12Device* device, const wchar_t* name = L"REFD2D D3D12CommandContext object");
virtual ~D3D12CommandContext() { reset(); }

void reset();
void wait(uint32_t ms);
void execute(ID3D12CommandQueue* queue);

void begin() { m_has_commands = true; }
ComPtr<ID3D12GraphicsCommandList>& begin();
void end(ID3D12CommandQueue* queue);

[[nodiscard]] bool is_setup() const { return m_is_setup; }
[[nodiscard]] ComPtr<ID3D12GraphicsCommandList>& cmd_list() { return m_cmd_list; }

private:
ComPtr<ID3D12CommandAllocator> m_cmd_allocator{};
Expand All @@ -34,7 +29,5 @@ class CommandContext {
std::recursive_mutex m_mtx{};

bool m_waiting_for_fence{};
bool m_has_commands{};
bool m_is_setup{};
};
} // namespace d3d12
};
13 changes: 4 additions & 9 deletions src/D3D12Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ D3D12Renderer::D3D12Renderer(IDXGISwapChain* swapchain_, ID3D12Device* device_,
// Create a command context for each back buffer.
// We create one for each because the GPU could be doing work on one while we're recording commands on another,
// before we submit them to the command queue. If we did not do this, we would run into some race conditions.
auto cmd_context = std::make_unique<d3d12::CommandContext>(m_device.Get());
auto cmd_context = std::make_unique<D3D12CommandContext>(m_device.Get());

if (cmd_context->is_setup()) {
m_cmd_contexts.push_back(std::move(cmd_context));
Expand Down Expand Up @@ -296,12 +296,7 @@ D3D12Renderer::D3D12Renderer(IDXGISwapChain* swapchain_, ID3D12Device* device_,
void D3D12Renderer::render(std::function<void(D2DPainter&)> draw_fn, bool update_d2d) {
auto& cmd_context = m_cmd_contexts[m_swapchain->GetCurrentBackBufferIndex() % m_cmd_contexts.size()];
auto& resources = m_render_resources[m_swapchain->GetCurrentBackBufferIndex() % m_render_resources.size()];

// Wait for the command context to be ready.
cmd_context->wait(INFINITE);
cmd_context->begin();

auto& cmd_list = cmd_context->cmd_list();
auto& cmd_list = cmd_context->begin();
auto& vert_buffer = resources->vert_buffer;

if (update_d2d) {
Expand Down Expand Up @@ -376,6 +371,6 @@ void D3D12Renderer::render(std::function<void(D2DPainter&)> draw_fn, bool update
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
cmd_list->ResourceBarrier(1, &barrier);

// Execute calls Close() on the command list.
cmd_context->execute(m_cmd_queue.Get());
// end(...) calls Close() on the command list.
cmd_context->end(m_cmd_queue.Get());
}
2 changes: 1 addition & 1 deletion src/D3D12Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class D3D12Renderer {
};

uint32_t m_frames_in_flight{1};
std::vector<std::unique_ptr<d3d12::CommandContext>> m_cmd_contexts{};
std::vector<std::unique_ptr<D3D12CommandContext>> m_cmd_contexts{};
std::vector<std::unique_ptr<RenderResources>> m_render_resources{};

int m_width{};
Expand Down

0 comments on commit f83ecd5

Please sign in to comment.