From 0480a1650a4487363983d5c2b179c2411be7d7d5 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 20 Jun 2024 18:21:04 +0100 Subject: [PATCH] Updating framebuffer to use renderpass Vulkan framebuffer requires a renderpass to be defined before the framebuffer can be created. Currently in gles backend, this order is irrelevant, and is not defined in the graphics api. Added Graphics::RenderPass vector to the Graphics::FramebufferCreateInfo - this vector may have more than one compatible render pass in it. The first render pass will be used to create the framebuffer, but BeginRenderPass may use any of the defined render passes with that framebuffer (as long as they are compatible in vulkan, i.e. only differ by layout or load/store ops). Change-Id: I66ce8530a34bcb1da57461db5644771efe0af48c --- .../graphics-framebuffer-create-info.h | 28 +++++++++++++++------ dali/internal/render/common/render-manager.cpp | 18 ++++++-------- .../render/renderers/render-frame-buffer.cpp | 29 +++++++++++++--------- dali/internal/update/common/scene-graph-scene.cpp | 13 +++++++++- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/dali/graphics-api/graphics-framebuffer-create-info.h b/dali/graphics-api/graphics-framebuffer-create-info.h index a09bbd5..007d25e 100644 --- a/dali/graphics-api/graphics-framebuffer-create-info.h +++ b/dali/graphics-api/graphics-framebuffer-create-info.h @@ -2,7 +2,7 @@ #define DALI_GRAPHICS_FRAMEBUFFER_CREATE_INFO_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,8 @@ namespace Dali { namespace Graphics { +struct RenderPass; + /** * @brief Interface class for FramebufferCreateInfo types in the graphics API. */ @@ -109,6 +111,15 @@ struct FramebufferCreateInfo } /** + * @brief Set the render passes to be used by this framebuffer + */ + auto& SetRenderPasses(std::vector&& renderPasses_) + { + renderPasses = std::move(renderPasses_); + return *this; + } + + /** * @brief Sets allocation callbacks which will be used when object is created * and destroyed. * @@ -121,12 +132,13 @@ struct FramebufferCreateInfo return *this; } - GraphicsStructureType type{GraphicsStructureType::FRAMEBUFFER_CREATE_INFO_STRUCT}; - ExtensionCreateInfo* nextExtension{nullptr}; - std::vector colorAttachments{}; - DepthStencilAttachment depthStencilAttachment{}; - Extent2D size{}; - uint8_t multiSamplingLevel{0u}; + GraphicsStructureType type{GraphicsStructureType::FRAMEBUFFER_CREATE_INFO_STRUCT}; + ExtensionCreateInfo* nextExtension{nullptr}; + std::vector colorAttachments{}; + std::vector renderPasses; + DepthStencilAttachment depthStencilAttachment{}; + Extent2D size{}; + uint8_t multiSamplingLevel{0u}; const AllocationCallbacks* allocationCallbacks{nullptr}; }; @@ -134,4 +146,4 @@ struct FramebufferCreateInfo } // namespace Graphics } // namespace Dali -#endif // DALI_GRAPHICS_FRAMEBUFFER_CREATE_INFO_H \ No newline at end of file +#endif // DALI_GRAPHICS_FRAMEBUFFER_CREATE_INFO_H diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 5beba0c..529d464 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -64,7 +64,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_REN namespace { // TODO : Cache clean logic have some problem now. Just block it until bug resolved -//constexpr uint32_t CACHE_CLEAN_FRAME_COUNT = 600u; // 60fps * 10sec +// constexpr uint32_t CACHE_CLEAN_FRAME_COUNT = 600u; // 60fps * 10sec #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED) constexpr uint32_t SHRINK_TO_FIT_FRAME_COUNT = (1u << 8); ///< 256 frames. Make this value as power of 2. @@ -863,7 +863,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: uint32_t instructionCount = sceneObject->GetRenderInstructions().Count(mImpl->renderBufferIndex); - std::vector targetstoPresent; + std::vector targetsToPresent; Rect surfaceRect = sceneObject->GetSurfaceRect(); if(clippingRect == surfaceRect) @@ -1039,7 +1039,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: currentRenderPass = sceneObject->GetGraphicsRenderPass(loadOp, Graphics::AttachmentStoreOp::STORE); } - targetstoPresent.emplace_back(currentRenderTarget); + targetsToPresent.emplace_back(currentRenderTarget); if(!instruction.mIgnoreRenderToFbo && (instruction.mFrameBuffer != nullptr)) { @@ -1144,11 +1144,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mainCommandBuffer->EndRenderPass(syncObject); } - if(targetstoPresent.size() > 0u) + if(targetsToPresent.size() > 0u) { - DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) { - oss << "[" << targetstoPresent.size() << "]"; - }); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) + { oss << "[" << targetsToPresent.size() << "]"; }); } // Flush UBOs @@ -1156,12 +1155,11 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mImpl->renderAlgorithms.SubmitCommandBuffer(); mImpl->commandBufferSubmitted = true; - if(targetstoPresent.size() > 0u) { - std::sort(targetstoPresent.begin(), targetstoPresent.end()); + std::sort(targetsToPresent.begin(), targetsToPresent.end()); Graphics::RenderTarget* rt = nullptr; - for(auto& target : targetstoPresent) + for(auto& target : targetsToPresent) { if(target != rt) { diff --git a/dali/internal/render/renderers/render-frame-buffer.cpp b/dali/internal/render/renderers/render-frame-buffer.cpp index 25209a9..965d28b 100644 --- a/dali/internal/render/renderers/render-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-frame-buffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,16 +122,6 @@ bool FrameBuffer::CreateGraphicsObjects() } else { - mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject)); - - // Create render target - Graphics::RenderTargetCreateInfo rtInfo{}; - rtInfo - .SetFramebuffer(mGraphicsObject.get()) - .SetExtent({mWidth, mHeight}) - .SetPreTransform(0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT); - mRenderTarget = mGraphicsController->CreateRenderTarget(rtInfo, std::move(mRenderTarget)); - std::vector attachmentDescriptions; // Default behaviour for color attachments is to CLEAR and STORE @@ -174,7 +164,22 @@ bool FrameBuffer::CreateGraphicsObjects() attachmentDescriptions[0].SetLoadOp(Graphics::AttachmentLoadOp::DONT_CARE); mRenderPass.emplace_back(mGraphicsController->CreateRenderPass(rpInfo, nullptr)); - created = true; + std::vector renderPasses; + renderPasses.push_back(mRenderPass[0].get()); + renderPasses.push_back(mRenderPass[1].get()); + mCreateInfo.SetRenderPasses(std::move(renderPasses)); + + mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject)); + + // Create render target + Graphics::RenderTargetCreateInfo rtInfo{}; + rtInfo + .SetFramebuffer(mGraphicsObject.get()) + .SetExtent({mWidth, mHeight}) + .SetPreTransform(0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT); + + mRenderTarget = mGraphicsController->CreateRenderTarget(rtInfo, std::move(mRenderTarget)); + created = true; } } return created; diff --git a/dali/internal/update/common/scene-graph-scene.cpp b/dali/internal/update/common/scene-graph-scene.cpp index d30b192..8fb3088 100644 --- a/dali/internal/update/common/scene-graph-scene.cpp +++ b/dali/internal/update/common/scene-graph-scene.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,6 +84,17 @@ void Scene::Initialize(Graphics::Controller& graphicsController, Integration::De mClearValues.back().depthStencil.stencil = 0; } + // @todo Currently, AttachmentDescription does not contain the attachment. + // VK can get the color attachment from the frame buffer or the surface's framebuffer + // But, the surface framebuffer is "per frame", i.e. it depends on the buffer index which + // attachment is relevant. + // So, + // do we need a compatible render pass per buffer? i.e. should we have 4, not 2?! + // And, should we manage that here, or could VulkanRenderPass manage 2 separate vkHandles instead? + + // @todo These render passes should be used by the backend (somehow) to generate the vk render passes + // for each back-buffer's image, stored with the framebuffer. (not impl?) + Graphics::RenderPassCreateInfo rpInfo{}; rpInfo.SetAttachments(attachmentDescriptions); -- 2.7.4