Line data Source code
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_VULKAN_DEVICECOMMANDCONTEXT
19 : #define INCLUDED_RENDERER_VULKAN_DEVICECOMMANDCONTEXT
20 :
21 : #include "renderer/backend/IBuffer.h"
22 : #include "renderer/backend/IDeviceCommandContext.h"
23 :
24 : #include <glad/vulkan.h>
25 : #include <memory>
26 : #include <vector>
27 :
28 : namespace Renderer
29 : {
30 :
31 : namespace Backend
32 : {
33 :
34 : namespace Vulkan
35 : {
36 :
37 : class CBuffer;
38 : class CDevice;
39 : class CFramebuffer;
40 : class CGraphicsPipelineState;
41 : class CRingCommandContext;
42 : class CShaderProgram;
43 : class CVertexInputLayout;
44 :
45 0 : class CDeviceCommandContext final : public IDeviceCommandContext
46 : {
47 : public:
48 : ~CDeviceCommandContext() override;
49 :
50 : IDevice* GetDevice() override;
51 :
52 : void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) override;
53 :
54 : void BlitFramebuffer(IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) override;
55 :
56 : void ClearFramebuffer(const bool color, const bool depth, const bool stencil) override;
57 : void BeginFramebufferPass(IFramebuffer* framebuffer) override;
58 : void EndFramebufferPass() override;
59 : void ReadbackFramebufferSync(
60 : const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height,
61 : void* data) override;
62 :
63 : void UploadTexture(ITexture* texture, const Format dataFormat,
64 : const void* data, const size_t dataSize,
65 : const uint32_t level = 0, const uint32_t layer = 0) override;
66 : void UploadTextureRegion(ITexture* texture, const Format dataFormat,
67 : const void* data, const size_t dataSize,
68 : const uint32_t xOffset, const uint32_t yOffset,
69 : const uint32_t width, const uint32_t height,
70 : const uint32_t level = 0, const uint32_t layer = 0) override;
71 :
72 : void UploadBuffer(IBuffer* buffer, const void* data, const uint32_t dataSize) override;
73 : void UploadBuffer(IBuffer* buffer, const UploadBufferFunction& uploadFunction) override;
74 : void UploadBufferRegion(
75 : IBuffer* buffer, const void* data, const uint32_t dataOffset, const uint32_t dataSize) override;
76 : void UploadBufferRegion(
77 : IBuffer* buffer, const uint32_t dataOffset, const uint32_t dataSize,
78 : const UploadBufferFunction& uploadFunction) override;
79 :
80 : void SetScissors(const uint32_t scissorCount, const Rect* scissors) override;
81 : void SetViewports(const uint32_t viewportCount, const Rect* viewports) override;
82 :
83 : void SetVertexInputLayout(
84 : IVertexInputLayout* vertexInputLayout) override;
85 :
86 : void SetVertexBuffer(
87 : const uint32_t bindingSlot, IBuffer* buffer, const uint32_t offset) override;
88 : void SetVertexBufferData(
89 : const uint32_t bindingSlot, const void* data, const uint32_t dataSize) override;
90 :
91 : void SetIndexBuffer(IBuffer* buffer) override;
92 : void SetIndexBufferData(const void* data, const uint32_t dataSize) override;
93 :
94 : void BeginPass() override;
95 : void EndPass() override;
96 :
97 : void Draw(const uint32_t firstVertex, const uint32_t vertexCount) override;
98 : void DrawIndexed(
99 : const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) override;
100 : void DrawInstanced(
101 : const uint32_t firstVertex, const uint32_t vertexCount,
102 : const uint32_t firstInstance, const uint32_t instanceCount) override;
103 : void DrawIndexedInstanced(
104 : const uint32_t firstIndex, const uint32_t indexCount,
105 : const uint32_t firstInstance, const uint32_t instanceCount,
106 : const int32_t vertexOffset) override;
107 : void DrawIndexedInRange(
108 : const uint32_t firstIndex, const uint32_t indexCount,
109 : const uint32_t start, const uint32_t end) override;
110 :
111 : void SetTexture(const int32_t bindingSlot, ITexture* texture) override;
112 :
113 : void SetUniform(
114 : const int32_t bindingSlot,
115 : const float value) override;
116 : void SetUniform(
117 : const int32_t bindingSlot,
118 : const float valueX, const float valueY) override;
119 : void SetUniform(
120 : const int32_t bindingSlot,
121 : const float valueX, const float valueY,
122 : const float valueZ) override;
123 : void SetUniform(
124 : const int32_t bindingSlot,
125 : const float valueX, const float valueY,
126 : const float valueZ, const float valueW) override;
127 : void SetUniform(
128 : const int32_t bindingSlot, PS::span<const float> values) override;
129 :
130 : void BeginScopedLabel(const char* name) override;
131 : void EndScopedLabel() override;
132 :
133 : void Flush() override;
134 :
135 : private:
136 : friend class CDevice;
137 :
138 : static std::unique_ptr<IDeviceCommandContext> Create(CDevice* device);
139 :
140 : CDeviceCommandContext();
141 :
142 : void PreDraw();
143 : void ApplyPipelineStateIfDirty();
144 : void BindVertexBuffer(const uint32_t bindingSlot, CBuffer* buffer, uint32_t offset);
145 : void BindIndexBuffer(CBuffer* buffer, uint32_t offset);
146 :
147 : CDevice* m_Device = nullptr;
148 :
149 : bool m_DebugScopedLabels = false;
150 :
151 : std::unique_ptr<CRingCommandContext> m_PrependCommandContext;
152 : std::unique_ptr<CRingCommandContext> m_CommandContext;
153 :
154 : CGraphicsPipelineState* m_GraphicsPipelineState = nullptr;
155 : CVertexInputLayout* m_VertexInputLayout = nullptr;
156 : CFramebuffer* m_Framebuffer = nullptr;
157 : CShaderProgram* m_ShaderProgram = nullptr;
158 : bool m_IsPipelineStateDirty = true;
159 : VkPipeline m_LastBoundPipeline = VK_NULL_HANDLE;
160 :
161 : bool m_InsideFramebufferPass = false;
162 : bool m_InsidePass = false;
163 :
164 : // Currently bound buffers to skip the same buffer bind.
165 : CBuffer* m_BoundIndexBuffer = nullptr;
166 : uint32_t m_BoundIndexBufferOffset = 0;
167 :
168 : // TODO: reduce code duplication.
169 : std::unique_ptr<CBuffer> m_UniformBuffer;
170 : std::unique_ptr<CBuffer> m_UniformStagingBuffer;
171 : VkDescriptorPool m_UniformDescriptorPool = VK_NULL_HANDLE;
172 : VkDescriptorSet m_UniformDescriptorSet = VK_NULL_HANDLE;
173 : // TODO: combine buffers.
174 : // Vertex buffer for in-place vertex data.
175 : std::unique_ptr<CBuffer> m_InPlaceVertexBuffer;
176 : std::unique_ptr<CBuffer> m_InPlaceIndexBuffer;
177 : std::unique_ptr<CBuffer> m_InPlaceVertexStagingBuffer;
178 : std::unique_ptr<CBuffer> m_InPlaceIndexStagingBuffer;
179 : void* m_InPlaceVertexStagingBufferMappedData = nullptr;
180 : void* m_InPlaceIndexStagingBufferMappedData = nullptr;
181 : void* m_UniformStagingBufferMappedData = nullptr;
182 : // TODO: add descriptions.
183 : uint32_t m_InPlaceBlockIndex = 0;
184 : uint32_t m_InPlaceBlockVertexOffset = 0;
185 : uint32_t m_InPlaceBlockIndexOffset = 0;
186 : uint32_t m_UniformOffset = 0;
187 : uint32_t m_UniformIndexOffset = 0;
188 : };
189 :
190 : } // namespace Vulkan
191 :
192 : } // namespace Backend
193 :
194 : } // namespace Renderer
195 :
196 : #endif // INCLUDED_RENDERER_VULKAN_DEVICECOMMANDCONTEXT
|