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