Pyrogenesis  trunk
RingCommandContext.h
Go to the documentation of this file.
1 /* Copyright (C) 2023 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_RENDERER_BACKEND_VULKAN_RINGCOMMANDCONTEXT
19 #define INCLUDED_RENDERER_BACKEND_VULKAN_RINGCOMMANDCONTEXT
20 
22 
23 #include <glad/vulkan.h>
24 #include <memory>
25 #include <vector>
26 
27 namespace Renderer
28 {
29 
30 namespace Backend
31 {
32 
33 namespace Vulkan
34 {
35 
36 class CBuffer;
37 class CDevice;
38 
39 /**
40  * A simple helper class to decouple command buffers rotation from frames
41  * presenting. It might be useful when sometimes we need to submit more work
42  * than we can usually have during a frame. For example if we need to upload
43  * something, an upload buffer is full and we can't extend it at the moment.
44  * Then the only way is to wait until uploading is done and submit more work.
45  * @note not thread-safe, should be created and used from the same thread.
46  */
48 {
49 public:
51  CDevice* device, const size_t size, const uint32_t queueFamilyIndex,
52  CSubmitScheduler& submitScheduler);
54 
55  /**
56  * @return the current available command buffer. If there is none waits until
57  * it appeared.
58  */
59  VkCommandBuffer GetCommandBuffer();
60 
61  /**
62  * Submits the current command buffer to the SubmitScheduler.
63  */
64  void Flush();
65 
66  /**
67  * Schedules uploads until next render pass or flush.
68  * @note doesn't save a command buffer returned by GetCommandBuffer during
69  * scheduling uploads, because it might be changed.
70  */
71  void ScheduleUpload(
72  CTexture* texture, const Format dataFormat,
73  const void* data, const size_t dataSize,
74  const uint32_t level, const uint32_t layer);
75  void ScheduleUpload(
76  CTexture* texture, const Format dataFormat,
77  const void* data, const size_t dataSize,
78  const uint32_t xOffset, const uint32_t yOffset,
79  const uint32_t width, const uint32_t height,
80  const uint32_t level, const uint32_t layer);
81 
82  void ScheduleUpload(
83  CBuffer* buffer, const void* data, const uint32_t dataOffset,
84  const uint32_t dataSize);
85  using UploadBufferFunction = std::function<void(u8*)>;
86  void ScheduleUpload(
87  CBuffer* buffer,
88  const uint32_t dataOffset, const uint32_t dataSize,
89  const UploadBufferFunction& uploadFunction);
90 
91 private:
92  void Begin();
93  void End();
94 
95  void ScheduleUpload(
96  CBuffer* buffer, const uint32_t dataOffset, const uint32_t dataSize,
97  const uint32_t acquiredOffset);
98 
100  const uint32_t requiredSize, const uint32_t requiredAlignment);
102  const uint32_t requiredSize, const uint32_t requiredAlignment) const;
103 
104  CDevice* m_Device = nullptr;
106 
107  std::unique_ptr<CBuffer> m_StagingBuffer;
111 
112  struct RingItem
113  {
114  VkCommandPool commandPool = VK_NULL_HANDLE;
115  VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
117  bool isBegan = false;
119  };
120  std::vector<RingItem> m_Ring;
121  size_t m_RingIndex = 0;
122 
123  void WaitUntilFree(RingItem& item);
124 };
125 
126 } // namespace Vulkan
127 
128 } // namespace Backend
129 
130 } // namespace Renderer
131 
132 #endif // INCLUDED_RENDERER_BACKEND_VULKAN_RINGCOMMANDCONTEXT
std::unique_ptr< CBuffer > m_StagingBuffer
Definition: RingCommandContext.h:107
size_t m_RingIndex
Definition: RingCommandContext.h:121
VkCommandBuffer commandBuffer
Definition: RingCommandContext.h:115
CDevice * m_Device
Definition: RingCommandContext.h:104
uint32_t m_StagingBufferLast
Definition: RingCommandContext.h:108
CSubmitScheduler & m_SubmitScheduler
Definition: RingCommandContext.h:105
uint32_t m_StagingBufferCurrentFirst
Definition: RingCommandContext.h:108
Definition: Buffer.h:38
void WaitUntilFree(RingItem &item)
Definition: RingCommandContext.cpp:320
A helper class to batch VkQueueSubmit calls and track VkCommandBuffer usages properly.
Definition: SubmitScheduler.h:46
Definition: Texture.h:39
Definition: Device.h:59
Format
Definition: Format.h:27
std::vector< RingItem > m_Ring
Definition: RingCommandContext.h:120
~CRingCommandContext()
Definition: RingCommandContext.cpp:91
uint32_t AcquireFreeSpace(const uint32_t requiredSize, const uint32_t requiredAlignment)
Definition: RingCommandContext.cpp:331
VkCommandBuffer GetCommandBuffer()
Definition: RingCommandContext.cpp:104
uint32_t m_MaxStagingBufferCapacity
Definition: RingCommandContext.h:110
uint32_t stagingBufferLast
Definition: RingCommandContext.h:118
bool isBegan
Definition: RingCommandContext.h:117
std::function< void(u8 *)> UploadBufferFunction
Definition: RingCommandContext.h:85
Backend
Definition: Backend.h:27
CRingCommandContext(CDevice *device, const size_t size, const uint32_t queueFamilyIndex, CSubmitScheduler &submitScheduler)
Definition: RingCommandContext.cpp:52
A simple helper class to decouple command buffers rotation from frames presenting.
Definition: RingCommandContext.h:47
CSubmitScheduler::SubmitHandle handle
Definition: RingCommandContext.h:116
uint32_t m_OptimalBufferCopyOffsetAlignment
Definition: RingCommandContext.h:109
unsigned int uint32_t
Definition: wposix_types.h:53
Definition: VideoMode.h:28
void Begin()
Definition: RingCommandContext.cpp:292
uint32_t GetFreeSpaceOffset(const uint32_t requiredSize, const uint32_t requiredAlignment) const
Definition: RingCommandContext.cpp:399
VkCommandPool commandPool
Definition: RingCommandContext.h:114
void ScheduleUpload(CTexture *texture, const Format dataFormat, const void *data, const size_t dataSize, const uint32_t level, const uint32_t layer)
Schedules uploads until next render pass or flush.
Definition: RingCommandContext.cpp:125
uint32_t SubmitHandle
Definition: SubmitScheduler.h:49
void Flush()
Submits the current command buffer to the SubmitScheduler.
Definition: RingCommandContext.cpp:112
uint32_t stagingBufferFirst
Definition: RingCommandContext.h:118
uint32_t m_StagingBufferFirst
Definition: RingCommandContext.h:108
void End()
Definition: RingCommandContext.cpp:310
static constexpr SubmitHandle INVALID_SUBMIT_HANDLE
Definition: SubmitScheduler.h:50