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