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