• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GLES_RENDER_BACKEND_GLES_H
17 #define GLES_RENDER_BACKEND_GLES_H
18 
19 #include <base/containers/string.h>
20 #include <base/containers/vector.h>
21 #include <render/namespace.h>
22 
23 #include "nodecontext/render_command_list.h"
24 #include "render_backend.h"
25 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
26 #include "device/gpu_buffer.h"
27 #include "perf/cpu_timer.h"
28 #include "perf/gpu_query_manager.h"
29 #endif
30 
31 RENDER_BEGIN_NAMESPACE()
32 class GpuShaderProgramGLES;
33 class GpuComputeProgramGLES;
34 class GpuSamplerGLES;
35 class GpuImageGLES;
36 class GpuBufferGLES;
37 class Device;
38 class DeviceGLES;
39 class GpuResourceManager;
40 class NodeContextPsoManager;
41 class NodeContextPoolManager;
42 class RenderBarrierList;
43 class RenderCommandList;
44 struct RenderCommandContext;
45 struct LowLevelCommandBuffer;
46 struct LowlevelFramebufferGL;
47 class ComputePipelineStateObjectGLES;
48 class GraphicsPipelineStateObjectGLES;
49 struct NodeGraphBackBufferConfiguration;
50 struct OES_Bind;
51 namespace Gles {
52 struct CombinedSamplerInfo;
53 struct PushConstantReflection;
54 struct BindMaps;
55 struct Bind;
56 } // namespace Gles
57 struct GpuBufferPlatformDataGL;
58 struct GpuSamplerPlatformDataGL;
59 struct GpuImagePlatformDataGL;
60 /**
61 RenderBackGLES.
62 OpenGLES 3.2+ render backend.
63 (also used for OpenGL 4.5+ on desktop)
64 **/
65 class RenderBackendGLES final : public RenderBackend {
66 public:
67     RenderBackendGLES(Device& device, GpuResourceManager& gpuResourceManager);
68     ~RenderBackendGLES();
69 
70     void Render(RenderCommandFrameData& renderCommandFrameData,
71         const RenderBackendBackBufferConfiguration& backBufferConfig) override;
72     void Present(const RenderBackendBackBufferConfiguration& backBufferConfig) override;
73 
74 private:
75     void RenderSingleCommandList(const RenderCommandContext& renderCommandCtx);
76     void RenderCommandDraw(const RenderCommandWithType&);
77     void RenderCommandDrawIndirect(const RenderCommandWithType&);
78     void RenderCommandDispatch(const RenderCommandWithType&);
79     void RenderCommandDispatchIndirect(const RenderCommandWithType&);
80     void RenderCommandBindPipeline(const RenderCommandWithType&);
81     void BindGraphicsPipeline(const struct RenderCommandBindPipeline&);
82     void BindComputePipeline(const struct RenderCommandBindPipeline&);
83     void RenderCommandBindVertexBuffers(const RenderCommandWithType&);
84     void RenderCommandBindIndexBuffer(const RenderCommandWithType&);
85     void RenderCommandBeginRenderPass(const RenderCommandWithType&);
86     void RenderCommandNextSubpass(const RenderCommandWithType&);
87     void RenderCommandEndRenderPass(const RenderCommandWithType&);
88     void RenderCommandCopyBuffer(const RenderCommandWithType&);
89     void RenderCommandCopyBufferImage(const RenderCommandWithType&);
90     void RenderCommandCopyImage(const RenderCommandWithType&);
91     void RenderCommandBlitImage(const RenderCommandWithType&);
92     void RenderCommandBarrierPoint(const RenderCommandWithType&);
93     void RenderCommandUpdateDescriptorSets(const RenderCommandWithType&);
94     void RenderCommandBindDescriptorSets(const RenderCommandWithType&);
95     void RenderCommandPushConstant(const RenderCommandWithType&);
96     void RenderCommandDynamicStateViewport(const RenderCommandWithType&);
97     void RenderCommandDynamicStateScissor(const RenderCommandWithType&);
98     void RenderCommandDynamicStateLineWidth(const RenderCommandWithType&);
99     void RenderCommandDynamicStateDepthBias(const RenderCommandWithType&);
100     void RenderCommandDynamicStateBlendConstants(const RenderCommandWithType&);
101     void RenderCommandDynamicStateDepthBounds(const RenderCommandWithType&);
102     void RenderCommandDynamicStateStencil(const RenderCommandWithType&);
103     void RenderCommandExecuteBackendFramePosition(const RenderCommandWithType&);
104     void RenderCommandWriteTimestamp(const RenderCommandWithType&);
105     void RenderCommandUndefined(const RenderCommandWithType&);
106     typedef void (RenderBackendGLES::*RenderCommandHandler)(const RenderCommandWithType&);
107     // Following array must match in order of RenderCommandType
108     // Count of render command types
109     static constexpr uint32_t RENDER_COMMAND_COUNT = ((uint32_t)RenderCommandType::GPU_QUEUE_TRANSFER_ACQUIRE) + 1u;
110     static constexpr RenderCommandHandler COMMAND_HANDLERS[RENDER_COMMAND_COUNT] = {
111         &RenderBackendGLES::RenderCommandUndefined, &RenderBackendGLES::RenderCommandDraw,
112         &RenderBackendGLES::RenderCommandDrawIndirect, &RenderBackendGLES::RenderCommandDispatch,
113         &RenderBackendGLES::RenderCommandDispatchIndirect, &RenderBackendGLES::RenderCommandBindPipeline,
114         &RenderBackendGLES::RenderCommandBeginRenderPass, &RenderBackendGLES::RenderCommandNextSubpass,
115         &RenderBackendGLES::RenderCommandEndRenderPass, &RenderBackendGLES::RenderCommandBindVertexBuffers,
116         &RenderBackendGLES::RenderCommandBindIndexBuffer, &RenderBackendGLES::RenderCommandCopyBuffer,
117         &RenderBackendGLES::RenderCommandCopyBufferImage, &RenderBackendGLES::RenderCommandCopyImage,
118         &RenderBackendGLES::RenderCommandBlitImage, &RenderBackendGLES::RenderCommandBarrierPoint,
119         &RenderBackendGLES::RenderCommandUpdateDescriptorSets, &RenderBackendGLES::RenderCommandBindDescriptorSets,
120         &RenderBackendGLES::RenderCommandPushConstant,
121         &RenderBackendGLES::RenderCommandUndefined, /* RenderCommandBuildAccelerationStructure */
122         &RenderBackendGLES::RenderCommandDynamicStateViewport, &RenderBackendGLES::RenderCommandDynamicStateScissor,
123         &RenderBackendGLES::RenderCommandDynamicStateLineWidth, &RenderBackendGLES::RenderCommandDynamicStateDepthBias,
124         &RenderBackendGLES::RenderCommandDynamicStateBlendConstants,
125         &RenderBackendGLES::RenderCommandDynamicStateDepthBounds, &RenderBackendGLES::RenderCommandDynamicStateStencil,
126         &RenderBackendGLES::RenderCommandExecuteBackendFramePosition, &RenderBackendGLES::RenderCommandWriteTimestamp,
127         &RenderBackendGLES::RenderCommandUndefined, /* RenderCommandGpuQueueTransferRelease */
128         &RenderBackendGLES::RenderCommandUndefined  /* RenderCommandGpuQueueTransferAcquire */
129     };
130     void PrimeCache(const GraphicsState& graphicsState); // Forces the graphics state..
131     void PrimeDepthStencilState(const GraphicsState& graphicsState);
132     void PrimeBlendState(const GraphicsState& graphicsState);
133     void DoGraphicsState(const GraphicsState& graphicsState);
134     void SetViewport(const RenderPassDesc::RenderArea& ra, const ViewportDesc& vd);
135     void SetScissor(const RenderPassDesc::RenderArea& ra, const ScissorDesc& sd);
136 
137     void HandleColorAttachments(const BASE_NS::array_view<const RenderPassDesc::AttachmentDesc*> colorAttachments);
138     void HandleDepthAttachment(const RenderPassDesc::AttachmentDesc& depthAttachment);
139 
140     void ClearScissorInit(const RenderPassDesc::RenderArea& aArea);
141     void ClearScissorSet();
142     void ClearScissorReset();
143     void SetPushConstant(uint32_t program, const Gles::PushConstantReflection& pc, const void* data);
144     void SetPushConstants(uint32_t program, const BASE_NS::array_view<Gles::PushConstantReflection>& pushConstants);
145     void DoSubPass(uint32_t subPass);
146 
147     struct Managers {
148         NodeContextPsoManager* psoMgr { nullptr };
149         NodeContextPoolManager* poolMgr { nullptr };
150         NodeContextDescriptorSetManager* descriptorSetMgr { nullptr };
151         const RenderBarrierList* rbList { nullptr };
152     };
153     Managers managers_;
154 
155     DeviceGLES& device_;
156     GpuResourceManager& gpuResourceMgr_;
157 
158     struct PresentationInfo {
159         uint32_t swapchainImageIndex { ~0u };
160     };
161     PresentationInfo presentationInfo_;
162 
163 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
164     struct PerfCounters {
165         uint32_t drawCount;
166         uint32_t drawIndirectCount;
167         uint32_t dispatchCount;
168         uint32_t dispatchIndirectCount;
169 
170         uint32_t renderPassCount;
171 
172         uint32_t bindProgram;
173         uint32_t bindSampler;
174         uint32_t bindTexture;
175         uint32_t bindBuffer;
176 
177         uint32_t triangleCount;
178         uint32_t instanceCount;
179     };
180     PerfCounters perfCounters_;
181 
182     bool validGpuQueries_;
183     BASE_NS::unique_ptr<GpuQueryManager> gpuQueryMgr_;
184     struct PerfDataSet {
185         EngineResourceHandle gpuHandle;
186         CpuTimer cpuTimer;
187     };
188     BASE_NS::unordered_map<BASE_NS::string, PerfDataSet> timers_;
189 
190     void StartFrameTimers(const RenderCommandFrameData& renderCommandFrameData);
191     void EndFrameTimers();
192     void CopyPerfTimeStamp(BASE_NS::string_view aName, PerfDataSet& perfDataSet);
193 
194     struct CommonBackendCpuTimers {
195         CpuTimer full;
196         CpuTimer acquire;
197         CpuTimer execute;
198         CpuTimer submit;
199         CpuTimer present;
200     };
201     CommonBackendCpuTimers commonCpuTimers_;
202 #endif
203     PolygonMode polygonMode_ = PolygonMode::CORE_POLYGON_MODE_FILL;
204     PrimitiveTopology topology_ = PrimitiveTopology::CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
205 
206     struct ProgramState {
207         bool setPushConstants { false };
208         struct RenderCommandPushConstant pushConstants {};
209     } boundProgram_;
210 
211     struct {
212         uint32_t id { 0 };
213         uintptr_t offset { 0 };
214         IndexType type { CORE_INDEX_TYPE_MAX_ENUM };
215     } boundIndexBuffer_;
216 
217     void ResetState();
218     void ResetBindings();
219     void SetupCache(const PipelineLayout& pipelineLayout);
220     struct BindState {
221         bool dirty { false };
222 #if defined(RENDER_HAS_GLES_BACKEND) && (RENDER_HAS_GLES_BACKEND == 1)
223         BASE_NS::vector<OES_Bind> oesBinds;
224 #endif
225         BASE_NS::vector<Gles::Bind> resources;
226     };
227     BindState boundObjects_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
228 
229     Gles::Bind& SetupBind(const DescriptorSetLayoutBinding& res, BASE_NS::vector<Gles::Bind>& resources);
230     void BindSampler(const BindableSampler& res, Gles::Bind& obj, uint32_t index);
231     void BindImage(const BindableImage& res, const GpuResourceState& resState, Gles::Bind& obj, uint32_t index);
232     void BindImageSampler(const BindableImage& res, const GpuResourceState& resState, Gles::Bind& obj, uint32_t index);
233     void BindBuffer(const BindableBuffer& res, Gles::Bind& obj, uint32_t dynamicOffset, uint32_t index);
234     void BindVertexInputs(
235         const VertexInputDeclarationData& decldata, const BASE_NS::array_view<const int32_t>& vertexInputs);
236     void ProcessBindings(const struct RenderCommandBindDescriptorSets& renderCmd,
237         const DescriptorSetLayoutBindingResources& data, uint32_t set, uint32_t& curDynamic);
238     void ScanPasses(const RenderPassDesc& rpd);
239     int32_t InvalidateColor(BASE_NS::array_view<uint32_t> invalidateAttachment, const RenderPassDesc& rpd,
240         const RenderPassSubpassDesc& currentSubPass);
241     int32_t InvalidateDepthStencil(BASE_NS::array_view<uint32_t> invalidateAttachment, const RenderPassDesc& rpd,
242         const RenderPassSubpassDesc& currentSubPass);
243     uint32_t ResolveMSAA(const RenderPassDesc& rpd, const RenderPassSubpassDesc& currentSubPass);
244     void UpdateBlendState(const GraphicsState& graphicsState);
245     void UpdateDepthState(const GraphicsState& graphicsState);
246     void UpdateStencilState(const GraphicsState& graphicsState);
247     void UpdateDepthStencilState(const GraphicsState& graphicsState);
248     void UpdateRasterizationState(const GraphicsState& graphicsState);
249     void BindResources();
250     enum StencilSetFlags { SETOP = 1, SETCOMPAREMASK = 2, SETCOMPAREOP = 4, SETREFERENCE = 8, SETWRITEMASK = 16 };
251     void SetStencilState(const uint32_t frontFlags, const GraphicsState::StencilOpState& front,
252         const uint32_t backFlags, const GraphicsState::StencilOpState& back);
253     const ComputePipelineStateObjectGLES* boundComputePipeline_ = nullptr;
254     const GraphicsPipelineStateObjectGLES* boundGraphicsPipeline_ = nullptr;
255     RenderHandle currentPsoHandle_;
256     RenderPassDesc::RenderArea renderArea_;
257     struct RenderCommandBeginRenderPass activeRenderPass_;
258     uint32_t currentSubPass_ = 0;
259     const LowlevelFramebufferGL* currentFrameBuffer_ = nullptr;
260     // caching state
261     GraphicsState cacheState_;
262     bool cachePrimed_ = false;
263     DynamicStateFlags dynamicStateFlags_ = DynamicStateFlagBits::CORE_DYNAMIC_STATE_UNDEFINED;
264     bool viewportPrimed_ = false;
265     bool clearScissorSet_ = false;
266     bool resetScissor_ = false;
267     RenderPassDesc::RenderArea clearScissor_;
268     bool scissorPrimed_ = false;
269     ScissorDesc scissorBox_;
270     ViewportDesc viewport_;
271 
272     static constexpr uint32_t MAX_VERTEXINPUT_BINDINGS { 16 };
273     uint32_t vertexAttribBinds_ = 0;
274     struct {
275         uint32_t id = 0;
276         intptr_t offset = 0;
277     } vertexAttribBindSlots_[MAX_VERTEXINPUT_BINDINGS];
278 
279     // attachments are cleared on first use, and marked as cleared here.
280     bool attachmentCleared_[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] = { false };
281     // subpass index where attachment is first used. (just for book keeping for now. clearing need is handled by
282     // "attachmentCleared" )
283     uint32_t attachmentFirstUse_[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] = { 0xFFFFFFFF };
284     // subpass index where attachment is last used. (for invalidation purposes)
285     uint32_t attachmentLastUse_[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] = { 0 };
286 
287     // will the attachment be resolved to backbuffer.. (if so flip coordinates)
288     bool resolveToBackbuffer_[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] = { false };
289     const GpuImageGLES* attachmentImage_[PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT] { nullptr };
290     bool multisampledRenderToTexture_ = false;
291 
292     uint32_t blitImageSourceFbo_ { 0 };
293     uint32_t blitImageDestinationFbo_ { 0 };
294     uint32_t inRenderpass_ { 0 };
295     bool scissorViewportSetDefaultFbo_ { false };
296     bool renderingToDefaultFbo_ { false };
297     bool scissorEnabled_ { false };
298     bool scissorBoxUpdated_ { false };
299     bool viewportDepthRangeUpdated_ { false };
300     bool viewportUpdated_ { false };
301     void FlushViewportScissors();
302 
303     void BufferToImageCopy(const struct RenderCommandCopyBufferImage& renderCmd);
304     void ImageToBufferCopy(const struct RenderCommandCopyBufferImage& renderCmd);
305 #if defined(RENDER_HAS_GLES_BACKEND) && (RENDER_HAS_GLES_BACKEND == 1)
306     BASE_NS::vector<OES_Bind> oesBinds_;
307 #endif
308 };
309 RENDER_END_NAMESPACE()
310 
311 #endif // GLES_RENDER_BACKEND_GLES_H
312