Merge 'remotes/trunk'
[0ad.git] / source / renderer / backend / IDeviceCommandContext.h
blobe6069bd50857132c77fb26df0c33de314df87702
1 /* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
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.
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.
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/>.
18 #ifndef INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT
19 #define INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT
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 #include "renderer/backend/Sampler.h"
27 #include <cstdint>
28 #include <functional>
30 namespace Renderer
33 namespace Backend
36 class IBuffer;
37 class IDevice;
38 class IFramebuffer;
39 class ITexture;
41 class IDeviceCommandContext : public IDeviceObject<IDeviceCommandContext>
43 public:
44 /**
45 * Binds the graphics pipeline state. It should be called only inside a
46 * framebuffer pass and as rarely as possible.
48 virtual void SetGraphicsPipelineState(IGraphicsPipelineState* pipelineState) = 0;
50 // TODO: maybe we should add a more common type, like CRectI.
51 struct Rect
53 int32_t x, y;
54 int32_t width, height;
56 /**
57 * Copies source region into destination region automatically applying
58 * compatible format conversion and scaling using a provided filter.
59 * A backbuffer can't be a source.
61 virtual void BlitFramebuffer(
62 IFramebuffer* sourceFramebuffer, IFramebuffer* destinationFramebuffer,
63 const Rect& sourceRegion, const Rect& destinationRegion,
64 const Sampler::Filter filter) = 0;
66 /**
67 * Resolves multisample source framebuffer attachments to destination
68 * attachments. Source attachments should have a sample count > 1 and
69 * destination attachments should have a sample count = 1.
70 * A backbuffer can't be a source.
72 virtual void ResolveFramebuffer(
73 IFramebuffer* sourceFramebuffer, IFramebuffer* destinationFramebuffer) = 0;
75 /**
76 * Starts a framebuffer pass, performs attachment load operations.
77 * It should be called as rarely as possible.
79 * @see IFramebuffer
81 virtual void BeginFramebufferPass(IFramebuffer* framebuffer) = 0;
83 /**
84 * Finishes a framebuffer pass, performs attachment store operations.
86 virtual void EndFramebufferPass() = 0;
88 /**
89 * Clears all mentioned attachments. Prefer to use attachment load operations over
90 * this function. It should be called only inside a framebuffer pass.
92 virtual void ClearFramebuffer(const bool color, const bool depth, const bool stencil) = 0;
94 /**
95 * Readbacks the current backbuffer to data in R8G8B8_UNORM format somewhen
96 * between the function call and Flush (inclusively). Because of that the
97 * data pointer should be valid in that time period and have enough space
98 * to fit the readback result.
99 * @note this operation is very slow and should not be used regularly.
100 * TODO: ideally we should do readback on Present or even asynchronously
101 * but a client doesn't support that yet.
103 virtual void ReadbackFramebufferSync(
104 const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height,
105 void* data) = 0;
107 virtual void UploadTexture(ITexture* texture, const Format dataFormat,
108 const void* data, const size_t dataSize,
109 const uint32_t level = 0, const uint32_t layer = 0) = 0;
110 virtual void UploadTextureRegion(ITexture* texture, const Format dataFormat,
111 const void* data, const size_t dataSize,
112 const uint32_t xOffset, const uint32_t yOffset,
113 const uint32_t width, const uint32_t height,
114 const uint32_t level = 0, const uint32_t layer = 0) = 0;
116 using UploadBufferFunction = std::function<void(u8*)>;
117 virtual void UploadBuffer(IBuffer* buffer, const void* data, const uint32_t dataSize) = 0;
118 virtual void UploadBuffer(IBuffer* buffer, const UploadBufferFunction& uploadFunction) = 0;
119 virtual void UploadBufferRegion(
120 IBuffer* buffer, const void* data, const uint32_t dataOffset, const uint32_t dataSize) = 0;
121 virtual void UploadBufferRegion(
122 IBuffer* buffer, const uint32_t dataOffset, const uint32_t dataSize,
123 const UploadBufferFunction& uploadFunction) = 0;
125 virtual void SetScissors(const uint32_t scissorCount, const Rect* scissors) = 0;
126 virtual void SetViewports(const uint32_t viewportCount, const Rect* viewports) = 0;
129 * Binds the vertex input layout. It should be compatible with the shader
130 * program's one. It should be called only inside a framebuffer pass and as
131 * rarely as possible.
133 virtual void SetVertexInputLayout(
134 IVertexInputLayout* vertexInputLayout) = 0;
136 virtual void SetVertexBuffer(
137 const uint32_t bindingSlot, IBuffer* buffer, const uint32_t offset) = 0;
138 virtual void SetVertexBufferData(
139 const uint32_t bindingSlot, const void* data, const uint32_t dataSize) = 0;
141 virtual void SetIndexBuffer(IBuffer* buffer) = 0;
142 virtual void SetIndexBufferData(const void* data, const uint32_t dataSize) = 0;
144 virtual void BeginPass() = 0;
145 virtual void EndPass() = 0;
147 virtual void Draw(const uint32_t firstVertex, const uint32_t vertexCount) = 0;
148 virtual void DrawIndexed(
149 const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) = 0;
150 virtual void DrawInstanced(
151 const uint32_t firstVertex, const uint32_t vertexCount,
152 const uint32_t firstInstance, const uint32_t instanceCount) = 0;
153 virtual void DrawIndexedInstanced(
154 const uint32_t firstIndex, const uint32_t indexCount,
155 const uint32_t firstInstance, const uint32_t instanceCount,
156 const int32_t vertexOffset) = 0;
157 // TODO: should be removed when performance impact is minimal on slow hardware.
158 virtual void DrawIndexedInRange(
159 const uint32_t firstIndex, const uint32_t indexCount,
160 const uint32_t start, const uint32_t end) = 0;
162 virtual void SetTexture(const int32_t bindingSlot, ITexture* texture) = 0;
164 virtual void SetUniform(
165 const int32_t bindingSlot,
166 const float value) = 0;
167 virtual void SetUniform(
168 const int32_t bindingSlot,
169 const float valueX, const float valueY) = 0;
170 virtual void SetUniform(
171 const int32_t bindingSlot,
172 const float valueX, const float valueY,
173 const float valueZ) = 0;
174 virtual void SetUniform(
175 const int32_t bindingSlot,
176 const float valueX, const float valueY,
177 const float valueZ, const float valueW) = 0;
178 virtual void SetUniform(
179 const int32_t bindingSlot, PS::span<const float> values) = 0;
181 virtual void BeginScopedLabel(const char* name) = 0;
182 virtual void EndScopedLabel() = 0;
184 virtual void Flush() = 0;
187 } // namespace Backend
189 } // namespace Renderer
191 #define GPU_SCOPED_LABEL(deviceCommandContext, name) \
192 GPUScopedLabel scopedLabel((deviceCommandContext), (name));
194 class GPUScopedLabel
196 public:
197 GPUScopedLabel(
198 Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
199 const char* name)
200 : m_DeviceCommandContext(deviceCommandContext)
202 m_DeviceCommandContext->BeginScopedLabel(name);
205 ~GPUScopedLabel()
207 m_DeviceCommandContext->EndScopedLabel();
210 private:
211 Renderer::Backend::IDeviceCommandContext* m_DeviceCommandContext = nullptr;
214 #endif // INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT