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