SleakEngine 0.1.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
DirectX12Buffer.hpp
Go to the documentation of this file.
1#ifndef DIRECTX12BUFFER_HPP_
2#define DIRECTX12BUFFER_HPP_
3#include <d3d12.h>
4#include <wrl/client.h>
5
6#include <cstdint>
7#include <memory>
8#include <vector>
9
11
12namespace Sleak {
13namespace RenderEngine {
15
16/// D3D12 buffer wrapper: default-heap resource plus an upload heap for CPU-to-GPU copies.
18public:
19 /// Uploads go through the shared uploader when given, else they block.
20 DirectX12Buffer(ID3D12Device* device, ID3D12CommandQueue* queue, size_t size,
21 BufferType type, DirectX12UploadContext* uploader = nullptr);
22
23 // Constructor for custom buffer configuration
24 DirectX12Buffer(ID3D12Device* device, size_t size, D3D12_HEAP_TYPE heapType,
25 D3D12_RESOURCE_STATES resourceState);
26
27 // Prevent copying
30
31 // Allow moving
33 DirectX12Buffer& operator=(DirectX12Buffer&&) noexcept;
34
35 ~DirectX12Buffer() override;
36 /// Creates the default-heap resource and uploads initial data via a staging
37 /// buffer, if any.
38 bool Initialize(void* Data) override;
39 void Update() override;
40 void Cleanup() override;
41
42 /// Maps the buffer for CPU writes (upload-heap buffers only).
43 bool Map() override;
44 void Unmap() override;
45 /// Overwrites buffer contents via a fresh upload-heap copy.
46 void Update(void* data, size_t size) override;
47 /// Creates the buffer sized and pre-populated from a raw payload.
48 bool Initialize(const void* data, size_t size);
49
50 void* GetData() override;
51
52 // Getter for the underlying D3D buffer
53 ID3D12Resource* GetD3DBuffer() const { return m_buffer.Get(); }
54
55 /// Latest constant buffer contents, copied into the upload ring on bind.
56 const void* GetConstantData() const {
57 return m_constantData.empty() ? nullptr : m_constantData.data();
58 }
59 size_t GetConstantDataSize() const { return m_constantData.size(); }
60
61 /// Ring address already holding the current contents for this frame, or 0.
62 D3D12_GPU_VIRTUAL_ADDRESS GetFrameAddress(uint64_t frame) const {
63 return m_frameSerial == frame ? m_frameAddress : 0;
64 }
65 /// Remembers where this frame's copy of the contents lives in the ring.
66 void SetFrameAddress(uint64_t frame, D3D12_GPU_VIRTUAL_ADDRESS address) {
67 m_frameSerial = frame;
68 m_frameAddress = address;
69 }
70
71 // Additional utility methods
72 bool IsValid() const { return m_buffer != nullptr; }
73 D3D12_HEAP_TYPE GetHeapType() const { return m_heapType; }
74 D3D12_RESOURCE_STATES GetResourceState() const { return m_resourceState; }
75
76private:
77 // Helper method to set up buffer description
78 D3D12_RESOURCE_DESC CreateBufferDesc() const;
79
80 // Convert BufferType to DirectX configuration
81 void ConfigureFromBufferType(BufferType type);
82
83 /// Records a staged copy into the default-heap buffer.
84 bool UploadToDefaultHeap(const void* data, size_t dataSize);
85
86 public:
87 /// Queues a GPU object for release once the frame that used it is done.
88 static void DeferCleanup(Microsoft::WRL::ComPtr<ID3D12Pageable> object);
89 /// Stamps everything queued since the last call with its retire value.
90 static void TagDeferredCleanup(uint64_t fenceValue);
91 /// Releases every queued object whose fence value has completed.
92 static void ProcessDeferredCleanup(uint64_t completedValue);
93
94 private:
95 // Smart pointers for proper resource management
96 Microsoft::WRL::ComPtr<ID3D12Device> m_device;
97 ID3D12CommandQueue* m_commandQueue = nullptr; // non-owning, for upload execution
98 DirectX12UploadContext* m_uploader = nullptr; // non-owning
99 Microsoft::WRL::ComPtr<ID3D12Resource> m_buffer;
100
101 D3D12_HEAP_TYPE m_heapType = D3D12_HEAP_TYPE_DEFAULT;
102 D3D12_RESOURCE_STATES m_resourceState = D3D12_RESOURCE_STATE_COMMON;
103 // Actual current GPU resource state (tracked for correct barriers on re-upload)
104 D3D12_RESOURCE_STATES m_currentState = D3D12_RESOURCE_STATE_COMMON;
105 void* m_mappedData = nullptr;
106
107 std::vector<uint8_t> m_constantData;
108 uint64_t m_frameSerial = 0;
109 D3D12_GPU_VIRTUAL_ADDRESS m_frameAddress = 0;
110};
111} // namespace RenderEngine
112} // namespace Sleak
113#endif // DIRECTX12BUFFER_HPP_
Backend-agnostic GPU buffer: vertex, index, constant, or resource view target.
void SetFrameAddress(uint64_t frame, D3D12_GPU_VIRTUAL_ADDRESS address)
Remembers where this frame's copy of the contents lives in the ring.
DirectX12Buffer(ID3D12Device *device, ID3D12CommandQueue *queue, size_t size, BufferType type, DirectX12UploadContext *uploader=nullptr)
Uploads go through the shared uploader when given, else they block.
static void TagDeferredCleanup(uint64_t fenceValue)
Stamps everything queued since the last call with its retire value.
const void * GetConstantData() const
Latest constant buffer contents, copied into the upload ring on bind.
D3D12_RESOURCE_STATES GetResourceState() const
D3D12_GPU_VIRTUAL_ADDRESS GetFrameAddress(uint64_t frame) const
Ring address already holding the current contents for this frame, or 0.
bool Map() override
Maps the buffer for CPU writes (upload-heap buffers only).
static void DeferCleanup(Microsoft::WRL::ComPtr< ID3D12Pageable > object)
Queues a GPU object for release once the frame that used it is done.
static void ProcessDeferredCleanup(uint64_t completedValue)
Releases every queued object whose fence value has completed.
DirectX12Buffer & operator=(const DirectX12Buffer &)=delete
ID3D12Resource * GetD3DBuffer() const
DirectX12Buffer(const DirectX12Buffer &)=delete
Backend-facing rendering layer shared by the four graphics backends.
BufferType
GPU buffer usage kind, drives backend binding flags and layout.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10