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_BACKEND_IDEVICECOMMANDCONTEXT
19 : #define INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT
20 :
21 : #include "ps/containers/Span.h"
22 : #include "renderer/backend/Format.h"
23 : #include "renderer/backend/IDeviceObject.h"
24 : #include "renderer/backend/PipelineState.h"
25 :
26 : #include <cstdint>
27 : #include <functional>
28 :
29 : namespace Renderer
30 : {
31 :
32 : namespace Backend
33 : {
34 :
35 : class IBuffer;
36 : class IDevice;
37 : class IFramebuffer;
38 : class ITexture;
39 :
40 12 : class IDeviceCommandContext : public IDeviceObject<IDeviceCommandContext>
41 : {
42 : public:
43 : /**
44 : * Binds the graphics pipeline state. It should be called only inside a
45 : * framebuffer pass and as rarely as possible.
46 : */
47 : virtual void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) = 0;
48 :
49 : virtual void BlitFramebuffer(
50 : IFramebuffer* destinationFramebuffer, IFramebuffer* sourceFramebuffer) = 0;
51 :
52 : /**
53 : * Starts a framebuffer pass, performs attachment load operations.
54 : * It should be called as rarely as possible.
55 : *
56 : * @see IFramebuffer
57 : */
58 : virtual void BeginFramebufferPass(IFramebuffer* framebuffer) = 0;
59 :
60 : /**
61 : * Finishes a framebuffer pass, performs attachment store operations.
62 : */
63 : virtual void EndFramebufferPass() = 0;
64 :
65 : /**
66 : * Clears all mentioned attachments. Prefer to use attachment load operations over
67 : * this function. It should be called only inside a framebuffer pass.
68 : */
69 : virtual void ClearFramebuffer(const bool color, const bool depth, const bool stencil) = 0;
70 :
71 : virtual void ReadbackFramebufferSync(
72 : const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height,
73 : void* data) = 0;
74 :
75 : virtual void UploadTexture(ITexture* texture, const Format dataFormat,
76 : const void* data, const size_t dataSize,
77 : const uint32_t level = 0, const uint32_t layer = 0) = 0;
78 : virtual void UploadTextureRegion(ITexture* texture, const Format dataFormat,
79 : const void* data, const size_t dataSize,
80 : const uint32_t xOffset, const uint32_t yOffset,
81 : const uint32_t width, const uint32_t height,
82 : const uint32_t level = 0, const uint32_t layer = 0) = 0;
83 :
84 : using UploadBufferFunction = std::function<void(u8*)>;
85 : virtual void UploadBuffer(IBuffer* buffer, const void* data, const uint32_t dataSize) = 0;
86 : virtual void UploadBuffer(IBuffer* buffer, const UploadBufferFunction& uploadFunction) = 0;
87 : virtual void UploadBufferRegion(
88 : IBuffer* buffer, const void* data, const uint32_t dataOffset, const uint32_t dataSize) = 0;
89 : virtual void UploadBufferRegion(
90 : IBuffer* buffer, const uint32_t dataOffset, const uint32_t dataSize,
91 : const UploadBufferFunction& uploadFunction) = 0;
92 :
93 : // TODO: maybe we should add a more common type, like CRectI.
94 : struct Rect
95 : {
96 : int32_t x, y;
97 : int32_t width, height;
98 : };
99 : virtual void SetScissors(const uint32_t scissorCount, const Rect* scissors) = 0;
100 : virtual void SetViewports(const uint32_t viewportCount, const Rect* viewports) = 0;
101 :
102 : /**
103 : * Binds the vertex input layout. It should be compatible with the shader
104 : * program's one. It should be called only inside a framebuffer pass and as
105 : * rarely as possible.
106 : */
107 : virtual void SetVertexInputLayout(
108 : IVertexInputLayout* vertexInputLayout) = 0;
109 :
110 : virtual void SetVertexBuffer(
111 : const uint32_t bindingSlot, IBuffer* buffer, const uint32_t offset) = 0;
112 : virtual void SetVertexBufferData(
113 : const uint32_t bindingSlot, const void* data, const uint32_t dataSize) = 0;
114 :
115 : virtual void SetIndexBuffer(IBuffer* buffer) = 0;
116 : virtual void SetIndexBufferData(const void* data, const uint32_t dataSize) = 0;
117 :
118 : virtual void BeginPass() = 0;
119 : virtual void EndPass() = 0;
120 :
121 : virtual void Draw(const uint32_t firstVertex, const uint32_t vertexCount) = 0;
122 : virtual void DrawIndexed(
123 : const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) = 0;
124 : virtual void DrawInstanced(
125 : const uint32_t firstVertex, const uint32_t vertexCount,
126 : const uint32_t firstInstance, const uint32_t instanceCount) = 0;
127 : virtual void DrawIndexedInstanced(
128 : const uint32_t firstIndex, const uint32_t indexCount,
129 : const uint32_t firstInstance, const uint32_t instanceCount,
130 : const int32_t vertexOffset) = 0;
131 : // TODO: should be removed when performance impact is minimal on slow hardware.
132 : virtual void DrawIndexedInRange(
133 : const uint32_t firstIndex, const uint32_t indexCount,
134 : const uint32_t start, const uint32_t end) = 0;
135 :
136 : virtual void SetTexture(const int32_t bindingSlot, ITexture* texture) = 0;
137 :
138 : virtual void SetUniform(
139 : const int32_t bindingSlot,
140 : const float value) = 0;
141 : virtual void SetUniform(
142 : const int32_t bindingSlot,
143 : const float valueX, const float valueY) = 0;
144 : virtual void SetUniform(
145 : const int32_t bindingSlot,
146 : const float valueX, const float valueY,
147 : const float valueZ) = 0;
148 : virtual void SetUniform(
149 : const int32_t bindingSlot,
150 : const float valueX, const float valueY,
151 : const float valueZ, const float valueW) = 0;
152 : virtual void SetUniform(
153 : const int32_t bindingSlot, PS::span<const float> values) = 0;
154 :
155 : virtual void BeginScopedLabel(const char* name) = 0;
156 : virtual void EndScopedLabel() = 0;
157 :
158 : virtual void Flush() = 0;
159 : };
160 :
161 : } // namespace Backend
162 :
163 : } // namespace Renderer
164 :
165 : #define GPU_SCOPED_LABEL(deviceCommandContext, name) \
166 : GPUScopedLabel scopedLabel((deviceCommandContext), (name));
167 :
168 : class GPUScopedLabel
169 : {
170 : public:
171 0 : GPUScopedLabel(
172 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
173 : const char* name)
174 0 : : m_DeviceCommandContext(deviceCommandContext)
175 : {
176 0 : m_DeviceCommandContext->BeginScopedLabel(name);
177 0 : }
178 :
179 0 : ~GPUScopedLabel()
180 0 : {
181 0 : m_DeviceCommandContext->EndScopedLabel();
182 0 : }
183 :
184 : private:
185 : Renderer::Backend::IDeviceCommandContext* m_DeviceCommandContext = nullptr;
186 : };
187 :
188 : #endif // INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT
|