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