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