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"
41 class IDeviceCommandContext
: public IDeviceObject
<IDeviceCommandContext
>
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.
54 int32_t width
, height
;
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;
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;
76 * Starts a framebuffer pass, performs attachment load operations.
77 * It should be called as rarely as possible.
81 virtual void BeginFramebufferPass(IFramebuffer
* framebuffer
) = 0;
84 * Finishes a framebuffer pass, performs attachment store operations.
86 virtual void EndFramebufferPass() = 0;
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;
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
,
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));
198 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
,
200 : m_DeviceCommandContext(deviceCommandContext
)
202 m_DeviceCommandContext
->BeginScopedLabel(name
);
207 m_DeviceCommandContext
->EndScopedLabel();
211 Renderer::Backend::IDeviceCommandContext
* m_DeviceCommandContext
= nullptr;
214 #endif // INCLUDED_RENDERER_BACKEND_IDEVICECOMMANDCONTEXT