18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "render_graph.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <cinttypes> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/array_view.h> 218bf80f4bSopenharmony_ci#include <base/containers/fixed_string.h> 228bf80f4bSopenharmony_ci#include <base/math/mathf.h> 238bf80f4bSopenharmony_ci#include <render/namespace.h> 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ci#include "device/gpu_resource_cache.h" 268bf80f4bSopenharmony_ci#include "device/gpu_resource_handle_util.h" 278bf80f4bSopenharmony_ci#include "device/gpu_resource_manager.h" 288bf80f4bSopenharmony_ci#include "nodecontext/render_barrier_list.h" 298bf80f4bSopenharmony_ci#include "nodecontext/render_command_list.h" 308bf80f4bSopenharmony_ci#include "nodecontext/render_node_graph_node_store.h" 318bf80f4bSopenharmony_ci#include "util/log.h" 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_ciusing namespace BASE_NS; 348bf80f4bSopenharmony_ci 358bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 368bf80f4bSopenharmony_cinamespace { 378bf80f4bSopenharmony_ciconstexpr uint32_t INVALID_TRACK_IDX { ~0u }; 388bf80f4bSopenharmony_ci 398bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 408bf80f4bSopenharmony_ciconstexpr const bool CORE_RENDER_GRAPH_FULL_DEBUG_PRINT = false; 418bf80f4bSopenharmony_ciconstexpr const bool CORE_RENDER_GRAPH_FULL_DEBUG_ATTACHMENTS = false; 428bf80f4bSopenharmony_ciconstexpr const bool CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES = false; 438bf80f4bSopenharmony_ci 448bf80f4bSopenharmony_civoid DebugPrintCommandListCommand(const RenderCommandWithType& rc, GpuResourceManager& aMgr) 458bf80f4bSopenharmony_ci{ 468bf80f4bSopenharmony_ci switch (rc.type) { 478bf80f4bSopenharmony_ci case RenderCommandType::BARRIER_POINT: { 488bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BarrierPoint"); 498bf80f4bSopenharmony_ci break; 508bf80f4bSopenharmony_ci } 518bf80f4bSopenharmony_ci case RenderCommandType::DRAW: { 528bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: Draw"); 538bf80f4bSopenharmony_ci break; 548bf80f4bSopenharmony_ci } 558bf80f4bSopenharmony_ci case RenderCommandType::DRAW_INDIRECT: { 568bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DrawIndirect"); 578bf80f4bSopenharmony_ci break; 588bf80f4bSopenharmony_ci } 598bf80f4bSopenharmony_ci case RenderCommandType::DISPATCH: { 608bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: Dispatch"); 618bf80f4bSopenharmony_ci break; 628bf80f4bSopenharmony_ci } 638bf80f4bSopenharmony_ci case RenderCommandType::DISPATCH_INDIRECT: { 648bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DispatchIndirect"); 658bf80f4bSopenharmony_ci break; 668bf80f4bSopenharmony_ci } 678bf80f4bSopenharmony_ci case RenderCommandType::BIND_PIPELINE: { 688bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BindPipeline"); 698bf80f4bSopenharmony_ci break; 708bf80f4bSopenharmony_ci } 718bf80f4bSopenharmony_ci case RenderCommandType::BEGIN_RENDER_PASS: { 728bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BeginRenderPass"); 738bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_FULL_DEBUG_ATTACHMENTS) { 748bf80f4bSopenharmony_ci const auto& beginRenderPass = *static_cast<RenderCommandBeginRenderPass*>(rc.rc); 758bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < beginRenderPass.renderPassDesc.attachmentCount; ++idx) { 768bf80f4bSopenharmony_ci const RenderHandle handle = beginRenderPass.renderPassDesc.attachmentHandles[idx]; 778bf80f4bSopenharmony_ci PLUGIN_LOG_I(" attachment idx: %u name: %s", idx, aMgr.GetName(handle).c_str()); 788bf80f4bSopenharmony_ci } 798bf80f4bSopenharmony_ci PLUGIN_LOG_I(" subpass count: %u, subpass start idx: %u", 808bf80f4bSopenharmony_ci (uint32_t)beginRenderPass.renderPassDesc.subpassCount, beginRenderPass.subpassStartIndex); 818bf80f4bSopenharmony_ci } 828bf80f4bSopenharmony_ci break; 838bf80f4bSopenharmony_ci } 848bf80f4bSopenharmony_ci case RenderCommandType::NEXT_SUBPASS: { 858bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: NextSubpass"); 868bf80f4bSopenharmony_ci break; 878bf80f4bSopenharmony_ci } 888bf80f4bSopenharmony_ci case RenderCommandType::END_RENDER_PASS: { 898bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: EndRenderPass"); 908bf80f4bSopenharmony_ci break; 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci case RenderCommandType::BIND_VERTEX_BUFFERS: { 938bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BindVertexBuffers"); 948bf80f4bSopenharmony_ci break; 958bf80f4bSopenharmony_ci } 968bf80f4bSopenharmony_ci case RenderCommandType::BIND_INDEX_BUFFER: { 978bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BindIndexBuffer"); 988bf80f4bSopenharmony_ci break; 998bf80f4bSopenharmony_ci } 1008bf80f4bSopenharmony_ci case RenderCommandType::COPY_BUFFER: { 1018bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: CopyBuffer"); 1028bf80f4bSopenharmony_ci break; 1038bf80f4bSopenharmony_ci } 1048bf80f4bSopenharmony_ci case RenderCommandType::COPY_BUFFER_IMAGE: { 1058bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: CopyBufferImage"); 1068bf80f4bSopenharmony_ci break; 1078bf80f4bSopenharmony_ci } 1088bf80f4bSopenharmony_ci case RenderCommandType::BIND_DESCRIPTOR_SETS: { 1098bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BindDescriptorSets"); 1108bf80f4bSopenharmony_ci break; 1118bf80f4bSopenharmony_ci } 1128bf80f4bSopenharmony_ci case RenderCommandType::PUSH_CONSTANT: { 1138bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: PushConstant"); 1148bf80f4bSopenharmony_ci break; 1158bf80f4bSopenharmony_ci } 1168bf80f4bSopenharmony_ci case RenderCommandType::BLIT_IMAGE: { 1178bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: BlitImage"); 1188bf80f4bSopenharmony_ci break; 1198bf80f4bSopenharmony_ci } 1208bf80f4bSopenharmony_ci // dynamic states 1218bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_VIEWPORT: { 1228bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateViewport"); 1238bf80f4bSopenharmony_ci break; 1248bf80f4bSopenharmony_ci } 1258bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_SCISSOR: { 1268bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateScissor"); 1278bf80f4bSopenharmony_ci break; 1288bf80f4bSopenharmony_ci } 1298bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_LINE_WIDTH: { 1308bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateLineWidth"); 1318bf80f4bSopenharmony_ci break; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_DEPTH_BIAS: { 1348bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateDepthBias"); 1358bf80f4bSopenharmony_ci break; 1368bf80f4bSopenharmony_ci } 1378bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_BLEND_CONSTANTS: { 1388bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateBlendConstants"); 1398bf80f4bSopenharmony_ci break; 1408bf80f4bSopenharmony_ci } 1418bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_DEPTH_BOUNDS: { 1428bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateDepthBounds"); 1438bf80f4bSopenharmony_ci break; 1448bf80f4bSopenharmony_ci } 1458bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_STENCIL: { 1468bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: DynamicStateStencil"); 1478bf80f4bSopenharmony_ci break; 1488bf80f4bSopenharmony_ci } 1498bf80f4bSopenharmony_ci case RenderCommandType::WRITE_TIMESTAMP: { 1508bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: WriteTimestamp"); 1518bf80f4bSopenharmony_ci break; 1528bf80f4bSopenharmony_ci } 1538bf80f4bSopenharmony_ci case RenderCommandType::GPU_QUEUE_TRANSFER_RELEASE: { 1548bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: GpuQueueTransferRelease"); 1558bf80f4bSopenharmony_ci break; 1568bf80f4bSopenharmony_ci } 1578bf80f4bSopenharmony_ci case RenderCommandType::GPU_QUEUE_TRANSFER_ACQUIRE: { 1588bf80f4bSopenharmony_ci PLUGIN_LOG_I("rc: GpuQueueTransferAcquire"); 1598bf80f4bSopenharmony_ci break; 1608bf80f4bSopenharmony_ci } 1618bf80f4bSopenharmony_ci case RenderCommandType::UNDEFINED: 1628bf80f4bSopenharmony_ci default: { 1638bf80f4bSopenharmony_ci PLUGIN_ASSERT(false && "non-valid render command"); 1648bf80f4bSopenharmony_ci break; 1658bf80f4bSopenharmony_ci } 1668bf80f4bSopenharmony_ci } 1678bf80f4bSopenharmony_ci} 1688bf80f4bSopenharmony_ci 1698bf80f4bSopenharmony_civoid DebugBarrierPrint(const GpuResourceManager& gpuResourceMgr, const vector<CommandBarrier>& combinedBarriers) 1708bf80f4bSopenharmony_ci{ 1718bf80f4bSopenharmony_ci PLUGIN_ASSERT(CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES); // do not call this function normally 1728bf80f4bSopenharmony_ci for (const auto& ref : combinedBarriers) { 1738bf80f4bSopenharmony_ci const RenderHandleType type = RenderHandleUtil::GetHandleType(ref.resourceHandle); 1748bf80f4bSopenharmony_ci if (type == RenderHandleType::GPU_BUFFER) { 1758bf80f4bSopenharmony_ci PLUGIN_LOG_I("barrier buffer :: handle:0x%" PRIx64 " name:%s, src_stage:%u dst_stage:%u", 1768bf80f4bSopenharmony_ci ref.resourceHandle.id, gpuResourceMgr.GetName(ref.resourceHandle).c_str(), ref.src.pipelineStageFlags, 1778bf80f4bSopenharmony_ci ref.dst.pipelineStageFlags); 1788bf80f4bSopenharmony_ci } else { 1798bf80f4bSopenharmony_ci PLUGIN_ASSERT(type == RenderHandleType::GPU_IMAGE); 1808bf80f4bSopenharmony_ci PLUGIN_LOG_I("barrier image :: handle:0x%" PRIx64 1818bf80f4bSopenharmony_ci " name:%s, src_stage:%u dst_stage:%u, src_layout:%u dst_layout:%u", 1828bf80f4bSopenharmony_ci ref.resourceHandle.id, gpuResourceMgr.GetName(ref.resourceHandle).c_str(), ref.src.pipelineStageFlags, 1838bf80f4bSopenharmony_ci ref.dst.pipelineStageFlags, ref.src.optionalImageLayout, ref.dst.optionalImageLayout); 1848bf80f4bSopenharmony_ci } 1858bf80f4bSopenharmony_ci } 1868bf80f4bSopenharmony_ci} 1878bf80f4bSopenharmony_ci 1888bf80f4bSopenharmony_civoid DebugRenderPassLayoutPrint(const GpuResourceManager& gpuResourceMgr, const RenderCommandBeginRenderPass& rc) 1898bf80f4bSopenharmony_ci{ 1908bf80f4bSopenharmony_ci PLUGIN_ASSERT(CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES); // do not call this function normally 1918bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < rc.renderPassDesc.attachmentCount; ++idx) { 1928bf80f4bSopenharmony_ci const auto handle = rc.renderPassDesc.attachmentHandles[idx]; 1938bf80f4bSopenharmony_ci const auto srcLayout = rc.imageLayouts.attachmentInitialLayouts[idx]; 1948bf80f4bSopenharmony_ci const auto dstLayout = rc.imageLayouts.attachmentFinalLayouts[idx]; 1958bf80f4bSopenharmony_ci PLUGIN_LOG_I("render_pass image :: handle:0x%" PRIx64 " name:%s, src_layout:%u dst_layout:%u (patched later)", 1968bf80f4bSopenharmony_ci handle.id, gpuResourceMgr.GetName(handle).c_str(), srcLayout, dstLayout); 1978bf80f4bSopenharmony_ci } 1988bf80f4bSopenharmony_ci} 1998bf80f4bSopenharmony_ci 2008bf80f4bSopenharmony_civoid DebugPrintImageState(const GpuResourceManager& gpuResourceMgr, const RenderGraph::RenderGraphImageState& resState) 2018bf80f4bSopenharmony_ci{ 2028bf80f4bSopenharmony_ci PLUGIN_ASSERT(CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES); // do not call this function normally 2038bf80f4bSopenharmony_ci const EngineResourceHandle gpuHandle = gpuResourceMgr.GetGpuHandle(resState.resource.handle); 2048bf80f4bSopenharmony_ci PLUGIN_LOG_I("image_state :: handle:0x%" PRIx64 " name:%s, layout:%u, index:%u, gen:%u, gpu_gen:%u", 2058bf80f4bSopenharmony_ci resState.resource.handle.id, gpuResourceMgr.GetName(resState.resource.handle).c_str(), 2068bf80f4bSopenharmony_ci resState.resource.imageLayout, RenderHandleUtil::GetIndexPart(resState.resource.handle), 2078bf80f4bSopenharmony_ci RenderHandleUtil::GetGenerationIndexPart(resState.resource.handle), 2088bf80f4bSopenharmony_ci RenderHandleUtil::GetGenerationIndexPart(gpuHandle)); 2098bf80f4bSopenharmony_ci // one could fetch and print vulkan handle here as well e.g. 2108bf80f4bSopenharmony_ci // 1. const GpuImagePlatformDataVk& plat = 2118bf80f4bSopenharmony_ci // 2. (const GpuImagePlatformDataVk&)gpuResourceMgr.GetImage(ref.first)->GetBasePlatformData() 2128bf80f4bSopenharmony_ci // 3. PLUGIN_LOG_I("end_frame image :: vk_handle:0x%" PRIx64, VulkanHandleCast<uint64_t>(plat.image)) 2138bf80f4bSopenharmony_ci} 2148bf80f4bSopenharmony_ci#endif // RENDER_DEV_ENABLED 2158bf80f4bSopenharmony_ci 2168bf80f4bSopenharmony_cistatic constexpr uint32_t WRITE_ACCESS_FLAGS = CORE_ACCESS_SHADER_WRITE_BIT | CORE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 2178bf80f4bSopenharmony_ci CORE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 2188bf80f4bSopenharmony_ci CORE_ACCESS_TRANSFER_WRITE_BIT | CORE_ACCESS_HOST_WRITE_BIT | 2198bf80f4bSopenharmony_ci CORE_ACCESS_MEMORY_WRITE_BIT; 2208bf80f4bSopenharmony_ci 2218bf80f4bSopenharmony_civoid PatchRenderPassFinalLayout(const RenderHandle handle, const ImageLayout imageLayout, 2228bf80f4bSopenharmony_ci RenderCommandBeginRenderPass& beginRenderPass, RenderGraph::RenderGraphImageState& storeState) 2238bf80f4bSopenharmony_ci{ 2248bf80f4bSopenharmony_ci const uint32_t attachmentCount = beginRenderPass.renderPassDesc.attachmentCount; 2258bf80f4bSopenharmony_ci for (uint32_t attachmentIdx = 0; attachmentIdx < attachmentCount; ++attachmentIdx) { 2268bf80f4bSopenharmony_ci if (beginRenderPass.renderPassDesc.attachmentHandles[attachmentIdx].id == handle.id) { 2278bf80f4bSopenharmony_ci beginRenderPass.imageLayouts.attachmentFinalLayouts[attachmentIdx] = imageLayout; 2288bf80f4bSopenharmony_ci storeState.resource.imageLayout = imageLayout; 2298bf80f4bSopenharmony_ci } 2308bf80f4bSopenharmony_ci } 2318bf80f4bSopenharmony_ci}; 2328bf80f4bSopenharmony_ci 2338bf80f4bSopenharmony_civoid UpdateMultiRenderCommandListRenderPasses(RenderGraph::MultiRenderPassStore& store) 2348bf80f4bSopenharmony_ci{ 2358bf80f4bSopenharmony_ci const uint32_t renderPassCount = (uint32_t)store.renderPasses.size(); 2368bf80f4bSopenharmony_ci PLUGIN_ASSERT(renderPassCount > 1); 2378bf80f4bSopenharmony_ci 2388bf80f4bSopenharmony_ci RenderCommandBeginRenderPass* firstRenderPass = store.renderPasses[0]; 2398bf80f4bSopenharmony_ci PLUGIN_ASSERT(firstRenderPass); 2408bf80f4bSopenharmony_ci PLUGIN_ASSERT(firstRenderPass->subpasses.size() >= renderPassCount); 2418bf80f4bSopenharmony_ci const RenderCommandBeginRenderPass* lastRenderPass = store.renderPasses[renderPassCount - 1]; 2428bf80f4bSopenharmony_ci PLUGIN_ASSERT(lastRenderPass); 2438bf80f4bSopenharmony_ci 2448bf80f4bSopenharmony_ci const uint32_t attachmentCount = firstRenderPass->renderPassDesc.attachmentCount; 2458bf80f4bSopenharmony_ci 2468bf80f4bSopenharmony_ci // take attachment loads from the first one, and stores from the last one 2478bf80f4bSopenharmony_ci // take initial layouts from the first one, and final layouts from the last one (could take the next layout) 2488bf80f4bSopenharmony_ci // initial store the correct render pass description to first render pass and then copy to others 2498bf80f4bSopenharmony_ci // resource states are copied from valid subpasses to another render command list subpasses 2508bf80f4bSopenharmony_ci for (uint32_t fromRpIdx = 0; fromRpIdx < renderPassCount; ++fromRpIdx) { 2518bf80f4bSopenharmony_ci const auto& fromRenderPass = *(store.renderPasses[fromRpIdx]); 2528bf80f4bSopenharmony_ci const uint32_t fromRpSubpassStartIndex = fromRenderPass.subpassStartIndex; 2538bf80f4bSopenharmony_ci const auto& fromRpSubpassResourceStates = fromRenderPass.subpassResourceStates[fromRpSubpassStartIndex]; 2548bf80f4bSopenharmony_ci for (uint32_t toRpIdx = 0; toRpIdx < renderPassCount; ++toRpIdx) { 2558bf80f4bSopenharmony_ci if (fromRpIdx != toRpIdx) { 2568bf80f4bSopenharmony_ci auto& toRenderPass = *(store.renderPasses[toRpIdx]); 2578bf80f4bSopenharmony_ci auto& toRpSubpassResourceStates = toRenderPass.subpassResourceStates[fromRpSubpassStartIndex]; 2588bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < attachmentCount; ++idx) { 2598bf80f4bSopenharmony_ci toRpSubpassResourceStates.states[idx] = fromRpSubpassResourceStates.states[idx]; 2608bf80f4bSopenharmony_ci toRpSubpassResourceStates.layouts[idx] = fromRpSubpassResourceStates.layouts[idx]; 2618bf80f4bSopenharmony_ci } 2628bf80f4bSopenharmony_ci } 2638bf80f4bSopenharmony_ci } 2648bf80f4bSopenharmony_ci } 2658bf80f4bSopenharmony_ci 2668bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < firstRenderPass->renderPassDesc.attachmentCount; ++idx) { 2678bf80f4bSopenharmony_ci firstRenderPass->renderPassDesc.attachments[idx].storeOp = 2688bf80f4bSopenharmony_ci lastRenderPass->renderPassDesc.attachments[idx].storeOp; 2698bf80f4bSopenharmony_ci firstRenderPass->renderPassDesc.attachments[idx].stencilStoreOp = 2708bf80f4bSopenharmony_ci lastRenderPass->renderPassDesc.attachments[idx].stencilStoreOp; 2718bf80f4bSopenharmony_ci 2728bf80f4bSopenharmony_ci firstRenderPass->imageLayouts.attachmentFinalLayouts[idx] = 2738bf80f4bSopenharmony_ci lastRenderPass->imageLayouts.attachmentFinalLayouts[idx]; 2748bf80f4bSopenharmony_ci } 2758bf80f4bSopenharmony_ci 2768bf80f4bSopenharmony_ci // copy subpasses to first 2778bf80f4bSopenharmony_ci for (uint32_t idx = 1; idx < renderPassCount; ++idx) { 2788bf80f4bSopenharmony_ci firstRenderPass->subpasses[idx] = store.renderPasses[idx]->subpasses[idx]; 2798bf80f4bSopenharmony_ci } 2808bf80f4bSopenharmony_ci 2818bf80f4bSopenharmony_ci // copy from first to following render passes 2828bf80f4bSopenharmony_ci for (uint32_t idx = 1; idx < renderPassCount; ++idx) { 2838bf80f4bSopenharmony_ci // subpass start index is the only changing variables 2848bf80f4bSopenharmony_ci const uint32_t subpassStartIndex = store.renderPasses[idx]->subpassStartIndex; 2858bf80f4bSopenharmony_ci store.renderPasses[idx]->renderPassDesc = firstRenderPass->renderPassDesc; 2868bf80f4bSopenharmony_ci store.renderPasses[idx]->subpassStartIndex = subpassStartIndex; 2878bf80f4bSopenharmony_ci 2888bf80f4bSopenharmony_ci // image layouts needs to match 2898bf80f4bSopenharmony_ci store.renderPasses[idx]->imageLayouts = firstRenderPass->imageLayouts; 2908bf80f4bSopenharmony_ci PLUGIN_ASSERT(store.renderPasses[idx]->subpasses.size() >= renderPassCount); 2918bf80f4bSopenharmony_ci // copy all subpasses 2928bf80f4bSopenharmony_ci if (!CloneData(store.renderPasses[idx]->subpasses.data(), sizeof(RenderPassSubpassDesc) * renderPassCount, 2938bf80f4bSopenharmony_ci firstRenderPass->subpasses.data(), sizeof(RenderPassSubpassDesc) * renderPassCount)) { 2948bf80f4bSopenharmony_ci PLUGIN_LOG_E("Copying of renderPasses failed."); 2958bf80f4bSopenharmony_ci } 2968bf80f4bSopenharmony_ci // copy input resource state 2978bf80f4bSopenharmony_ci if (!CloneData(store.renderPasses[idx]->inputResourceStates.states, sizeof(GpuResourceState) * attachmentCount, 2988bf80f4bSopenharmony_ci firstRenderPass->inputResourceStates.states, sizeof(GpuResourceState) * attachmentCount)) { 2998bf80f4bSopenharmony_ci PLUGIN_LOG_E("Copying of renderPasses failed."); 3008bf80f4bSopenharmony_ci } 3018bf80f4bSopenharmony_ci // NOTE: subpassResourceStates are not copied to different render passes 3028bf80f4bSopenharmony_ci } 3038bf80f4bSopenharmony_ci 3048bf80f4bSopenharmony_ci#if (RENDER_VULKAN_COMBINE_MULTI_COMMAND_LIST_MSAA_SUBPASSES_ENABLED == 1) 3058bf80f4bSopenharmony_ci // copy the final layouts and resolves to first render pass 3068bf80f4bSopenharmony_ci const uint32_t finalSubpassIdx = renderPassCount - 1U; 3078bf80f4bSopenharmony_ci if ((renderPassCount > 1U) && (firstRenderPass->subpasses[finalSubpassIdx].resolveAttachmentCount > 0U)) { 3088bf80f4bSopenharmony_ci firstRenderPass->renderPassDesc.subpassCount = 1U; 3098bf80f4bSopenharmony_ci firstRenderPass->subpasses = { firstRenderPass->subpasses.data(), 1U }; 3108bf80f4bSopenharmony_ci firstRenderPass->subpassResourceStates = { firstRenderPass->subpassResourceStates.data(), 1U }; 3118bf80f4bSopenharmony_ci // copy resolve attachments from the final subpass 3128bf80f4bSopenharmony_ci auto& firstSubpass = firstRenderPass->subpasses[0U]; 3138bf80f4bSopenharmony_ci const auto& finalSubpass = store.renderPasses[finalSubpassIdx]->subpasses[finalSubpassIdx]; 3148bf80f4bSopenharmony_ci firstSubpass.resolveAttachmentCount = finalSubpass.resolveAttachmentCount; 3158bf80f4bSopenharmony_ci firstSubpass.depthResolveAttachmentCount = finalSubpass.depthResolveAttachmentCount; 3168bf80f4bSopenharmony_ci firstSubpass.depthResolveAttachmentIndex = finalSubpass.depthResolveAttachmentIndex; 3178bf80f4bSopenharmony_ci firstSubpass.depthResolveModeFlagBit = finalSubpass.depthResolveModeFlagBit; 3188bf80f4bSopenharmony_ci CloneData(firstSubpass.resolveAttachmentIndices, sizeof(firstSubpass.resolveAttachmentIndices), 3198bf80f4bSopenharmony_ci finalSubpass.resolveAttachmentIndices, sizeof(uint32_t) * firstSubpass.resolveAttachmentCount); 3208bf80f4bSopenharmony_ci // layouts for resolve attachments 3218bf80f4bSopenharmony_ci const auto& finalSubpassResourceStates = 3228bf80f4bSopenharmony_ci store.renderPasses[finalSubpassIdx]->subpassResourceStates[finalSubpassIdx]; 3238bf80f4bSopenharmony_ci const uint32_t resolveAttachmentCount = firstSubpass.resolveAttachmentCount; 3248bf80f4bSopenharmony_ci for (uint32_t resIdx = 0U; resIdx < resolveAttachmentCount; ++resIdx) { 3258bf80f4bSopenharmony_ci const uint32_t resAttIdx = firstSubpass.resolveAttachmentIndices[resIdx]; 3268bf80f4bSopenharmony_ci firstRenderPass->subpassResourceStates[0U].layouts[resAttIdx] = 3278bf80f4bSopenharmony_ci finalSubpassResourceStates.layouts[resAttIdx]; 3288bf80f4bSopenharmony_ci firstRenderPass->subpassResourceStates[0U].states[resAttIdx] = finalSubpassResourceStates.states[resAttIdx]; 3298bf80f4bSopenharmony_ci } 3308bf80f4bSopenharmony_ci if ((firstSubpass.depthResolveAttachmentCount > 0U) && 3318bf80f4bSopenharmony_ci (firstSubpass.depthResolveAttachmentIndex < PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT)) { 3328bf80f4bSopenharmony_ci const uint32_t resAttIdx = firstSubpass.resolveAttachmentIndices[firstSubpass.depthResolveAttachmentIndex]; 3338bf80f4bSopenharmony_ci firstRenderPass->subpassResourceStates[0U].layouts[resAttIdx] = 3348bf80f4bSopenharmony_ci finalSubpassResourceStates.layouts[resAttIdx]; 3358bf80f4bSopenharmony_ci firstRenderPass->subpassResourceStates[0U].states[resAttIdx] = finalSubpassResourceStates.states[resAttIdx]; 3368bf80f4bSopenharmony_ci } 3378bf80f4bSopenharmony_ci 3388bf80f4bSopenharmony_ci // fix render command list indices 3398bf80f4bSopenharmony_ci for (uint32_t idx = 1; idx < renderPassCount; ++idx) { 3408bf80f4bSopenharmony_ci store.renderPasses[idx]->renderPassDesc = firstRenderPass->renderPassDesc; 3418bf80f4bSopenharmony_ci store.renderPasses[idx]->subpassStartIndex = 0U; 3428bf80f4bSopenharmony_ci store.renderPasses[idx]->subpasses = firstRenderPass->subpasses; 3438bf80f4bSopenharmony_ci store.renderPasses[idx]->subpassResourceStates = firstRenderPass->subpassResourceStates; 3448bf80f4bSopenharmony_ci } 3458bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 3468bf80f4bSopenharmony_ci PLUGIN_LOG_ONCE_I("combine_multi_command_list_msaa_subpasses_enabled", 3478bf80f4bSopenharmony_ci "RENDER_VALIDATION: Combining multi-commandlist MSAA resolve subpasses"); 3488bf80f4bSopenharmony_ci#endif 3498bf80f4bSopenharmony_ci } 3508bf80f4bSopenharmony_ci#endif 3518bf80f4bSopenharmony_ci} 3528bf80f4bSopenharmony_ci 3538bf80f4bSopenharmony_ciResourceBarrier GetSrcBufferBarrier(const GpuResourceState& state, const BindableBuffer& res) 3548bf80f4bSopenharmony_ci{ 3558bf80f4bSopenharmony_ci return { 3568bf80f4bSopenharmony_ci state.accessFlags, 3578bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 3588bf80f4bSopenharmony_ci ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED, 3598bf80f4bSopenharmony_ci res.byteOffset, 3608bf80f4bSopenharmony_ci res.byteSize, 3618bf80f4bSopenharmony_ci }; 3628bf80f4bSopenharmony_ci} 3638bf80f4bSopenharmony_ci 3648bf80f4bSopenharmony_ciResourceBarrier GetSrcImageBarrier(const GpuResourceState& state, const BindableImage& res) 3658bf80f4bSopenharmony_ci{ 3668bf80f4bSopenharmony_ci return { 3678bf80f4bSopenharmony_ci state.accessFlags, 3688bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 3698bf80f4bSopenharmony_ci res.imageLayout, 3708bf80f4bSopenharmony_ci 0, 3718bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 3728bf80f4bSopenharmony_ci }; 3738bf80f4bSopenharmony_ci} 3748bf80f4bSopenharmony_ci 3758bf80f4bSopenharmony_ciResourceBarrier GetSrcImageBarrierMips(const GpuResourceState& state, const BindableImage& src, 3768bf80f4bSopenharmony_ci const BindableImage& dst, const RenderGraph::RenderGraphAdditionalImageState& additionalImageState) 3778bf80f4bSopenharmony_ci{ 3788bf80f4bSopenharmony_ci uint32_t mipLevel = 0U; 3798bf80f4bSopenharmony_ci uint32_t mipCount = PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS; 3808bf80f4bSopenharmony_ci ImageLayout srcImageLayout = src.imageLayout; 3818bf80f4bSopenharmony_ci if ((src.mip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS) || 3828bf80f4bSopenharmony_ci (dst.mip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS)) { 3838bf80f4bSopenharmony_ci if (dst.mip < RenderGraph::MAX_MIP_STATE_COUNT) { 3848bf80f4bSopenharmony_ci mipLevel = dst.mip; 3858bf80f4bSopenharmony_ci mipCount = 1U; 3868bf80f4bSopenharmony_ci } else { 3878bf80f4bSopenharmony_ci mipLevel = src.mip; 3888bf80f4bSopenharmony_ci // all mip levels 3898bf80f4bSopenharmony_ci } 3908bf80f4bSopenharmony_ci PLUGIN_ASSERT(additionalImageState.layouts); 3918bf80f4bSopenharmony_ci srcImageLayout = additionalImageState.layouts[mipLevel]; 3928bf80f4bSopenharmony_ci } 3938bf80f4bSopenharmony_ci return { 3948bf80f4bSopenharmony_ci state.accessFlags, 3958bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 3968bf80f4bSopenharmony_ci srcImageLayout, 3978bf80f4bSopenharmony_ci 0, 3988bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 3998bf80f4bSopenharmony_ci { 0, mipLevel, mipCount, 0u, PipelineStateConstants::GPU_IMAGE_ALL_LAYERS }, 4008bf80f4bSopenharmony_ci }; 4018bf80f4bSopenharmony_ci} 4028bf80f4bSopenharmony_ci 4038bf80f4bSopenharmony_ciResourceBarrier GetDstBufferBarrier(const GpuResourceState& state, const BindableBuffer& res) 4048bf80f4bSopenharmony_ci{ 4058bf80f4bSopenharmony_ci return { 4068bf80f4bSopenharmony_ci state.accessFlags, 4078bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 4088bf80f4bSopenharmony_ci ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED, 4098bf80f4bSopenharmony_ci res.byteOffset, 4108bf80f4bSopenharmony_ci res.byteSize, 4118bf80f4bSopenharmony_ci }; 4128bf80f4bSopenharmony_ci} 4138bf80f4bSopenharmony_ci 4148bf80f4bSopenharmony_ciResourceBarrier GetDstImageBarrier(const GpuResourceState& state, const BindableImage& res) 4158bf80f4bSopenharmony_ci{ 4168bf80f4bSopenharmony_ci return { 4178bf80f4bSopenharmony_ci state.accessFlags, 4188bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 4198bf80f4bSopenharmony_ci res.imageLayout, 4208bf80f4bSopenharmony_ci 0, 4218bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 4228bf80f4bSopenharmony_ci }; 4238bf80f4bSopenharmony_ci} 4248bf80f4bSopenharmony_ci 4258bf80f4bSopenharmony_ciResourceBarrier GetDstImageBarrierMips(const GpuResourceState& state, const BindableImage& src, 4268bf80f4bSopenharmony_ci const BindableImage& dst, const RenderGraph::RenderGraphAdditionalImageState& additionalImageState) 4278bf80f4bSopenharmony_ci{ 4288bf80f4bSopenharmony_ci uint32_t mipLevel = 0U; 4298bf80f4bSopenharmony_ci uint32_t mipCount = PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS; 4308bf80f4bSopenharmony_ci ImageLayout dstImageLayout = dst.imageLayout; 4318bf80f4bSopenharmony_ci if ((src.mip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS) || 4328bf80f4bSopenharmony_ci (dst.mip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS)) { 4338bf80f4bSopenharmony_ci if (dst.mip < RenderGraph::MAX_MIP_STATE_COUNT) { 4348bf80f4bSopenharmony_ci mipLevel = dst.mip; 4358bf80f4bSopenharmony_ci mipCount = 1U; 4368bf80f4bSopenharmony_ci } else { 4378bf80f4bSopenharmony_ci mipLevel = src.mip; 4388bf80f4bSopenharmony_ci // all mip levels 4398bf80f4bSopenharmony_ci } 4408bf80f4bSopenharmony_ci } 4418bf80f4bSopenharmony_ci return { 4428bf80f4bSopenharmony_ci state.accessFlags, 4438bf80f4bSopenharmony_ci state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 4448bf80f4bSopenharmony_ci dstImageLayout, 4458bf80f4bSopenharmony_ci 0, 4468bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 4478bf80f4bSopenharmony_ci { 0, mipLevel, mipCount, 0u, PipelineStateConstants::GPU_IMAGE_ALL_LAYERS }, 4488bf80f4bSopenharmony_ci }; 4498bf80f4bSopenharmony_ci} 4508bf80f4bSopenharmony_ci 4518bf80f4bSopenharmony_civoid ModifyAdditionalImageState( 4528bf80f4bSopenharmony_ci const BindableImage& res, RenderGraph::RenderGraphAdditionalImageState& additionalStateRef) 4538bf80f4bSopenharmony_ci{ 4548bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 4558bf80f4bSopenharmony_ci // NOTE: should not be called for images without CORE_RESOURCE_HANDLE_ADDITIONAL_STATE 4568bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::IsDynamicAdditionalStateResource(res.handle)); 4578bf80f4bSopenharmony_ci#endif 4588bf80f4bSopenharmony_ci if (additionalStateRef.layouts) { 4598bf80f4bSopenharmony_ci if ((res.mip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS) && 4608bf80f4bSopenharmony_ci (res.mip < RenderGraph::MAX_MIP_STATE_COUNT)) { 4618bf80f4bSopenharmony_ci additionalStateRef.layouts[res.mip] = res.imageLayout; 4628bf80f4bSopenharmony_ci } else { 4638bf80f4bSopenharmony_ci // set layout for all mips 4648bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < RenderGraph::MAX_MIP_STATE_COUNT; ++idx) { 4658bf80f4bSopenharmony_ci additionalStateRef.layouts[idx] = res.imageLayout; 4668bf80f4bSopenharmony_ci } 4678bf80f4bSopenharmony_ci } 4688bf80f4bSopenharmony_ci } else { 4698bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 4708bf80f4bSopenharmony_ci PLUGIN_LOG_ONCE_E(to_hex(res.handle.id), "mip layouts missing"); 4718bf80f4bSopenharmony_ci#endif 4728bf80f4bSopenharmony_ci } 4738bf80f4bSopenharmony_ci} 4748bf80f4bSopenharmony_ci 4758bf80f4bSopenharmony_ciCommandBarrier GetQueueOwnershipTransferBarrier(const RenderHandle handle, const GpuQueue& srcGpuQueue, 4768bf80f4bSopenharmony_ci const GpuQueue& dstGpuQueue, const ImageLayout srcImageLayout, const ImageLayout dstImageLayout) 4778bf80f4bSopenharmony_ci{ 4788bf80f4bSopenharmony_ci return { 4798bf80f4bSopenharmony_ci handle, 4808bf80f4bSopenharmony_ci 4818bf80f4bSopenharmony_ci ResourceBarrier { 4828bf80f4bSopenharmony_ci 0, 4838bf80f4bSopenharmony_ci PipelineStageFlagBits::CORE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 4848bf80f4bSopenharmony_ci srcImageLayout, 4858bf80f4bSopenharmony_ci 0, 4868bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 4878bf80f4bSopenharmony_ci ImageSubresourceRange {}, 4888bf80f4bSopenharmony_ci }, 4898bf80f4bSopenharmony_ci srcGpuQueue, 4908bf80f4bSopenharmony_ci 4918bf80f4bSopenharmony_ci ResourceBarrier { 4928bf80f4bSopenharmony_ci 0, 4938bf80f4bSopenharmony_ci PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 4948bf80f4bSopenharmony_ci dstImageLayout, 4958bf80f4bSopenharmony_ci 0, 4968bf80f4bSopenharmony_ci PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE, 4978bf80f4bSopenharmony_ci ImageSubresourceRange {}, 4988bf80f4bSopenharmony_ci }, 4998bf80f4bSopenharmony_ci dstGpuQueue, 5008bf80f4bSopenharmony_ci }; 5018bf80f4bSopenharmony_ci} 5028bf80f4bSopenharmony_ci 5038bf80f4bSopenharmony_civoid PatchGpuResourceQueueTransfers(array_view<const RenderNodeContextData> frameRenderNodeContextData, 5048bf80f4bSopenharmony_ci array_view<const RenderGraph::GpuQueueTransferState> currNodeGpuResourceTransfers) 5058bf80f4bSopenharmony_ci{ 5068bf80f4bSopenharmony_ci for (const auto& transferRef : currNodeGpuResourceTransfers) { 5078bf80f4bSopenharmony_ci PLUGIN_ASSERT(transferRef.acquireNodeIdx < (uint32_t)frameRenderNodeContextData.size()); 5088bf80f4bSopenharmony_ci 5098bf80f4bSopenharmony_ci auto& acquireNodeRef = frameRenderNodeContextData[transferRef.acquireNodeIdx]; 5108bf80f4bSopenharmony_ci const GpuQueue acquireGpuQueue = acquireNodeRef.renderCommandList->GetGpuQueue(); 5118bf80f4bSopenharmony_ci GpuQueue releaseGpuQueue = acquireGpuQueue; 5128bf80f4bSopenharmony_ci 5138bf80f4bSopenharmony_ci if (transferRef.releaseNodeIdx < (uint32_t)frameRenderNodeContextData.size()) { 5148bf80f4bSopenharmony_ci auto& releaseNodeRef = frameRenderNodeContextData[transferRef.releaseNodeIdx]; 5158bf80f4bSopenharmony_ci releaseGpuQueue = releaseNodeRef.renderCommandList->GetGpuQueue(); 5168bf80f4bSopenharmony_ci } 5178bf80f4bSopenharmony_ci 5188bf80f4bSopenharmony_ci const CommandBarrier transferBarrier = GetQueueOwnershipTransferBarrier(transferRef.handle, releaseGpuQueue, 5198bf80f4bSopenharmony_ci acquireGpuQueue, transferRef.optionalReleaseImageLayout, transferRef.optionalAcquireImageLayout); 5208bf80f4bSopenharmony_ci 5218bf80f4bSopenharmony_ci // release ownership (NOTE: not done for previous frame) 5228bf80f4bSopenharmony_ci if (transferRef.releaseNodeIdx < (uint32_t)frameRenderNodeContextData.size()) { 5238bf80f4bSopenharmony_ci auto& releaseNodeRef = frameRenderNodeContextData[transferRef.releaseNodeIdx]; 5248bf80f4bSopenharmony_ci const uint32_t rcIndex = releaseNodeRef.renderCommandList->GetRenderCommandCount() - 1; 5258bf80f4bSopenharmony_ci const RenderCommandWithType& cmdRef = releaseNodeRef.renderCommandList->GetRenderCommands()[rcIndex]; 5268bf80f4bSopenharmony_ci PLUGIN_ASSERT(cmdRef.type == RenderCommandType::BARRIER_POINT); 5278bf80f4bSopenharmony_ci const auto& rcbp = *static_cast<RenderCommandBarrierPoint*>(cmdRef.rc); 5288bf80f4bSopenharmony_ci PLUGIN_ASSERT(rcbp.renderCommandType == RenderCommandType::GPU_QUEUE_TRANSFER_RELEASE); 5298bf80f4bSopenharmony_ci 5308bf80f4bSopenharmony_ci const uint32_t barrierPointIndex = rcbp.barrierPointIndex; 5318bf80f4bSopenharmony_ci releaseNodeRef.renderBarrierList->AddBarriersToBarrierPoint(barrierPointIndex, { transferBarrier }); 5328bf80f4bSopenharmony_ci 5338bf80f4bSopenharmony_ci // inform that we are patching valid barriers 5348bf80f4bSopenharmony_ci releaseNodeRef.renderCommandList->SetValidGpuQueueReleaseAcquireBarriers(); 5358bf80f4bSopenharmony_ci } 5368bf80f4bSopenharmony_ci // acquire ownership 5378bf80f4bSopenharmony_ci { 5388bf80f4bSopenharmony_ci const uint32_t rcIndex = 0; 5398bf80f4bSopenharmony_ci const RenderCommandWithType& cmdRef = acquireNodeRef.renderCommandList->GetRenderCommands()[rcIndex]; 5408bf80f4bSopenharmony_ci PLUGIN_ASSERT(cmdRef.type == RenderCommandType::BARRIER_POINT); 5418bf80f4bSopenharmony_ci const auto& rcbp = *static_cast<RenderCommandBarrierPoint*>(cmdRef.rc); 5428bf80f4bSopenharmony_ci PLUGIN_ASSERT(rcbp.renderCommandType == RenderCommandType::GPU_QUEUE_TRANSFER_ACQUIRE); 5438bf80f4bSopenharmony_ci 5448bf80f4bSopenharmony_ci const uint32_t barrierPointIndex = rcbp.barrierPointIndex; 5458bf80f4bSopenharmony_ci acquireNodeRef.renderBarrierList->AddBarriersToBarrierPoint(barrierPointIndex, { transferBarrier }); 5468bf80f4bSopenharmony_ci 5478bf80f4bSopenharmony_ci // inform that we are patching valid barriers 5488bf80f4bSopenharmony_ci acquireNodeRef.renderCommandList->SetValidGpuQueueReleaseAcquireBarriers(); 5498bf80f4bSopenharmony_ci } 5508bf80f4bSopenharmony_ci } 5518bf80f4bSopenharmony_ci} 5528bf80f4bSopenharmony_ci 5538bf80f4bSopenharmony_cibool CheckForBarrierNeed(const unordered_map<RenderHandle, uint32_t>& handledCustomBarriers, 5548bf80f4bSopenharmony_ci const uint32_t customBarrierCount, const RenderHandle handle) 5558bf80f4bSopenharmony_ci{ 5568bf80f4bSopenharmony_ci bool needsBarrier = RenderHandleUtil::IsDynamicResource(handle); 5578bf80f4bSopenharmony_ci if ((customBarrierCount > 0) && needsBarrier) { 5588bf80f4bSopenharmony_ci needsBarrier = (handledCustomBarriers.count(handle) > 0) ? false : true; 5598bf80f4bSopenharmony_ci } 5608bf80f4bSopenharmony_ci return needsBarrier; 5618bf80f4bSopenharmony_ci} 5628bf80f4bSopenharmony_ci} // namespace 5638bf80f4bSopenharmony_ci 5648bf80f4bSopenharmony_ciRenderGraph::RenderGraph(GpuResourceManager& gpuResourceMgr) : gpuResourceMgr_(gpuResourceMgr) {} 5658bf80f4bSopenharmony_ci 5668bf80f4bSopenharmony_civoid RenderGraph::BeginFrame() 5678bf80f4bSopenharmony_ci{ 5688bf80f4bSopenharmony_ci stateCache_.multiRenderPassStore.renderPasses.clear(); 5698bf80f4bSopenharmony_ci stateCache_.multiRenderPassStore.firstRenderPassBarrierList = nullptr; 5708bf80f4bSopenharmony_ci stateCache_.multiRenderPassStore.firstBarrierPointIndex = ~0u; 5718bf80f4bSopenharmony_ci stateCache_.multiRenderPassStore.supportOpen = false; 5728bf80f4bSopenharmony_ci stateCache_.nodeCounter = 0u; 5738bf80f4bSopenharmony_ci stateCache_.checkForBackbufferDependency = false; 5748bf80f4bSopenharmony_ci stateCache_.usesSwapchainImage = false; 5758bf80f4bSopenharmony_ci} 5768bf80f4bSopenharmony_ci 5778bf80f4bSopenharmony_civoid RenderGraph::ProcessRenderNodeGraph( 5788bf80f4bSopenharmony_ci const bool checkBackbufferDependancy, const array_view<RenderNodeGraphNodeStore*> renderNodeGraphNodeStores) 5798bf80f4bSopenharmony_ci{ 5808bf80f4bSopenharmony_ci stateCache_.checkForBackbufferDependency = checkBackbufferDependancy; 5818bf80f4bSopenharmony_ci 5828bf80f4bSopenharmony_ci // NOTE: separate gpu buffers and gpu images due to larger structs, layers, mips in images 5838bf80f4bSopenharmony_ci // all levels of mips and layers are not currently tracked -> needs more fine grained modifications 5848bf80f4bSopenharmony_ci // handles: 5858bf80f4bSopenharmony_ci // gpu images in descriptor sets, render passes, blits, and custom barriers 5868bf80f4bSopenharmony_ci // gpu buffers in descriptor sets, and custom barriers 5878bf80f4bSopenharmony_ci 5888bf80f4bSopenharmony_ci { 5898bf80f4bSopenharmony_ci // remove resources that will not be tracked anymore and release available slots 5908bf80f4bSopenharmony_ci const GpuResourceManager::StateDestroyConsumeStruct stateResetData = gpuResourceMgr_.ConsumeStateDestroyData(); 5918bf80f4bSopenharmony_ci for (const auto& handle : stateResetData.resources) { 5928bf80f4bSopenharmony_ci const RenderHandleType handleType = RenderHandleUtil::GetHandleType(handle); 5938bf80f4bSopenharmony_ci const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle); 5948bf80f4bSopenharmony_ci if ((handleType == RenderHandleType::GPU_IMAGE) && 5958bf80f4bSopenharmony_ci (arrayIndex < static_cast<uint32_t>(gpuImageDataIndices_.size()))) { 5968bf80f4bSopenharmony_ci if (const uint32_t dataIdx = gpuImageDataIndices_[arrayIndex]; dataIdx != INVALID_TRACK_IDX) { 5978bf80f4bSopenharmony_ci PLUGIN_ASSERT(dataIdx < static_cast<uint32_t>(gpuImageTracking_.size())); 5988bf80f4bSopenharmony_ci gpuImageTracking_[dataIdx] = {}; // reset 5998bf80f4bSopenharmony_ci gpuImageAvailableIndices_.push_back(dataIdx); 6008bf80f4bSopenharmony_ci } 6018bf80f4bSopenharmony_ci gpuImageDataIndices_[arrayIndex] = INVALID_TRACK_IDX; 6028bf80f4bSopenharmony_ci } else if (arrayIndex < static_cast<uint32_t>(gpuBufferDataIndices_.size())) { 6038bf80f4bSopenharmony_ci if (const uint32_t dataIdx = gpuBufferDataIndices_[arrayIndex]; dataIdx != INVALID_TRACK_IDX) { 6048bf80f4bSopenharmony_ci PLUGIN_ASSERT(dataIdx < static_cast<uint32_t>(gpuBufferTracking_.size())); 6058bf80f4bSopenharmony_ci gpuBufferTracking_[dataIdx] = {}; // reset 6068bf80f4bSopenharmony_ci gpuBufferAvailableIndices_.push_back(dataIdx); 6078bf80f4bSopenharmony_ci } 6088bf80f4bSopenharmony_ci gpuBufferDataIndices_[arrayIndex] = INVALID_TRACK_IDX; 6098bf80f4bSopenharmony_ci } 6108bf80f4bSopenharmony_ci } 6118bf80f4bSopenharmony_ci } 6128bf80f4bSopenharmony_ci 6138bf80f4bSopenharmony_ci gpuBufferDataIndices_.resize(gpuResourceMgr_.GetBufferHandleCount(), INVALID_TRACK_IDX); 6148bf80f4bSopenharmony_ci gpuImageDataIndices_.resize(gpuResourceMgr_.GetImageHandleCount(), INVALID_TRACK_IDX); 6158bf80f4bSopenharmony_ci 6168bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 6178bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_FULL_DEBUG_PRINT || CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES || 6188bf80f4bSopenharmony_ci CORE_RENDER_GRAPH_FULL_DEBUG_ATTACHMENTS) { 6198bf80f4bSopenharmony_ci static uint64_t debugFrame = 0; 6208bf80f4bSopenharmony_ci debugFrame++; 6218bf80f4bSopenharmony_ci PLUGIN_LOG_I("START RENDER GRAPH, FRAME %" PRIu64, debugFrame); 6228bf80f4bSopenharmony_ci } 6238bf80f4bSopenharmony_ci#endif 6248bf80f4bSopenharmony_ci 6258bf80f4bSopenharmony_ci // need to store some of the resource for frame state in undefined state (i.e. reset on frame boundaries) 6268bf80f4bSopenharmony_ci ProcessRenderNodeGraphNodeStores(renderNodeGraphNodeStores, stateCache_); 6278bf80f4bSopenharmony_ci 6288bf80f4bSopenharmony_ci // store final state for next frame 6298bf80f4bSopenharmony_ci StoreFinalBufferState(); 6308bf80f4bSopenharmony_ci StoreFinalImageState(); // processes gpuImageBackbufferState_ as well 6318bf80f4bSopenharmony_ci} 6328bf80f4bSopenharmony_ci 6338bf80f4bSopenharmony_ciRenderGraph::SwapchainStates RenderGraph::GetSwapchainResourceStates() const 6348bf80f4bSopenharmony_ci{ 6358bf80f4bSopenharmony_ci return swapchainStates_; 6368bf80f4bSopenharmony_ci} 6378bf80f4bSopenharmony_ci 6388bf80f4bSopenharmony_civoid RenderGraph::ProcessRenderNodeGraphNodeStores( 6398bf80f4bSopenharmony_ci const array_view<RenderNodeGraphNodeStore*>& renderNodeGraphNodeStores, StateCache& stateCache) 6408bf80f4bSopenharmony_ci{ 6418bf80f4bSopenharmony_ci for (RenderNodeGraphNodeStore* graphStore : renderNodeGraphNodeStores) { 6428bf80f4bSopenharmony_ci PLUGIN_ASSERT(graphStore); 6438bf80f4bSopenharmony_ci if (!graphStore) { 6448bf80f4bSopenharmony_ci continue; 6458bf80f4bSopenharmony_ci } 6468bf80f4bSopenharmony_ci 6478bf80f4bSopenharmony_ci for (uint32_t nodeIdx = 0; nodeIdx < (uint32_t)graphStore->renderNodeContextData.size(); ++nodeIdx) { 6488bf80f4bSopenharmony_ci auto& ref = graphStore->renderNodeContextData[nodeIdx]; 6498bf80f4bSopenharmony_ci ref.submitInfo.waitForSwapchainAcquireSignal = false; // reset 6508bf80f4bSopenharmony_ci stateCache.usesSwapchainImage = false; // reset 6518bf80f4bSopenharmony_ci 6528bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 6538bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_FULL_DEBUG_PRINT) { 6548bf80f4bSopenharmony_ci PLUGIN_LOG_I("FULL NODENAME %s", graphStore->renderNodeData[nodeIdx].fullName.data()); 6558bf80f4bSopenharmony_ci } 6568bf80f4bSopenharmony_ci#endif 6578bf80f4bSopenharmony_ci 6588bf80f4bSopenharmony_ci if (stateCache.multiRenderPassStore.supportOpen && 6598bf80f4bSopenharmony_ci (stateCache.multiRenderPassStore.renderPasses.size() == 0)) { 6608bf80f4bSopenharmony_ci PLUGIN_LOG_E("invalid multi render node render pass subpass stitching"); 6618bf80f4bSopenharmony_ci // NOTE: add more error handling and invalidate render command lists 6628bf80f4bSopenharmony_ci } 6638bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.supportOpen = ref.renderCommandList->HasMultiRenderCommandListSubpasses(); 6648bf80f4bSopenharmony_ci array_view<const RenderCommandWithType> cmdListRef = ref.renderCommandList->GetRenderCommands(); 6658bf80f4bSopenharmony_ci // go through commands that affect or need transitions and barriers 6668bf80f4bSopenharmony_ci ProcessRenderNodeCommands(cmdListRef, nodeIdx, ref, stateCache); 6678bf80f4bSopenharmony_ci 6688bf80f4bSopenharmony_ci // needs backbuffer/swapchain wait 6698bf80f4bSopenharmony_ci if (stateCache.usesSwapchainImage) { 6708bf80f4bSopenharmony_ci ref.submitInfo.waitForSwapchainAcquireSignal = true; 6718bf80f4bSopenharmony_ci } 6728bf80f4bSopenharmony_ci 6738bf80f4bSopenharmony_ci // patch gpu resource queue transfers 6748bf80f4bSopenharmony_ci if (!currNodeGpuResourceTransfers_.empty()) { 6758bf80f4bSopenharmony_ci PatchGpuResourceQueueTransfers(graphStore->renderNodeContextData, currNodeGpuResourceTransfers_); 6768bf80f4bSopenharmony_ci // clear for next use 6778bf80f4bSopenharmony_ci currNodeGpuResourceTransfers_.clear(); 6788bf80f4bSopenharmony_ci } 6798bf80f4bSopenharmony_ci 6808bf80f4bSopenharmony_ci stateCache_.nodeCounter++; 6818bf80f4bSopenharmony_ci } 6828bf80f4bSopenharmony_ci } 6838bf80f4bSopenharmony_ci} 6848bf80f4bSopenharmony_ci 6858bf80f4bSopenharmony_civoid RenderGraph::ProcessRenderNodeCommands(array_view<const RenderCommandWithType>& cmdListRef, 6868bf80f4bSopenharmony_ci const uint32_t& nodeIdx, RenderNodeContextData& ref, StateCache& stateCache) 6878bf80f4bSopenharmony_ci{ 6888bf80f4bSopenharmony_ci for (uint32_t listIdx = 0; listIdx < (uint32_t)cmdListRef.size(); ++listIdx) { 6898bf80f4bSopenharmony_ci auto& cmdRef = cmdListRef[listIdx]; 6908bf80f4bSopenharmony_ci 6918bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 6928bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_FULL_DEBUG_PRINT) { 6938bf80f4bSopenharmony_ci DebugPrintCommandListCommand(cmdRef, gpuResourceMgr_); 6948bf80f4bSopenharmony_ci } 6958bf80f4bSopenharmony_ci#endif 6968bf80f4bSopenharmony_ci 6978bf80f4bSopenharmony_ci // most of the commands are handled within BarrierPoint 6988bf80f4bSopenharmony_ci switch (cmdRef.type) { 6998bf80f4bSopenharmony_ci case RenderCommandType::BARRIER_POINT: 7008bf80f4bSopenharmony_ci RenderCommand(nodeIdx, listIdx, ref, *static_cast<RenderCommandBarrierPoint*>(cmdRef.rc), stateCache); 7018bf80f4bSopenharmony_ci break; 7028bf80f4bSopenharmony_ci 7038bf80f4bSopenharmony_ci case RenderCommandType::BEGIN_RENDER_PASS: 7048bf80f4bSopenharmony_ci RenderCommand( 7058bf80f4bSopenharmony_ci nodeIdx, listIdx, ref, *static_cast<RenderCommandBeginRenderPass*>(cmdRef.rc), stateCache); 7068bf80f4bSopenharmony_ci break; 7078bf80f4bSopenharmony_ci 7088bf80f4bSopenharmony_ci case RenderCommandType::END_RENDER_PASS: 7098bf80f4bSopenharmony_ci RenderCommand(nodeIdx, listIdx, ref, *static_cast<RenderCommandEndRenderPass*>(cmdRef.rc), stateCache); 7108bf80f4bSopenharmony_ci break; 7118bf80f4bSopenharmony_ci 7128bf80f4bSopenharmony_ci case RenderCommandType::NEXT_SUBPASS: 7138bf80f4bSopenharmony_ci case RenderCommandType::DRAW: 7148bf80f4bSopenharmony_ci case RenderCommandType::DRAW_INDIRECT: 7158bf80f4bSopenharmony_ci case RenderCommandType::DISPATCH: 7168bf80f4bSopenharmony_ci case RenderCommandType::DISPATCH_INDIRECT: 7178bf80f4bSopenharmony_ci case RenderCommandType::BIND_PIPELINE: 7188bf80f4bSopenharmony_ci case RenderCommandType::BIND_VERTEX_BUFFERS: 7198bf80f4bSopenharmony_ci case RenderCommandType::BIND_INDEX_BUFFER: 7208bf80f4bSopenharmony_ci case RenderCommandType::COPY_BUFFER: 7218bf80f4bSopenharmony_ci case RenderCommandType::COPY_BUFFER_IMAGE: 7228bf80f4bSopenharmony_ci case RenderCommandType::COPY_IMAGE: 7238bf80f4bSopenharmony_ci case RenderCommandType::BIND_DESCRIPTOR_SETS: 7248bf80f4bSopenharmony_ci case RenderCommandType::PUSH_CONSTANT: 7258bf80f4bSopenharmony_ci case RenderCommandType::BLIT_IMAGE: 7268bf80f4bSopenharmony_ci case RenderCommandType::BUILD_ACCELERATION_STRUCTURE: 7278bf80f4bSopenharmony_ci case RenderCommandType::CLEAR_COLOR_IMAGE: 7288bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_VIEWPORT: 7298bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_SCISSOR: 7308bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_LINE_WIDTH: 7318bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_DEPTH_BIAS: 7328bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_BLEND_CONSTANTS: 7338bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_DEPTH_BOUNDS: 7348bf80f4bSopenharmony_ci case RenderCommandType::DYNAMIC_STATE_STENCIL: 7358bf80f4bSopenharmony_ci case RenderCommandType::WRITE_TIMESTAMP: 7368bf80f4bSopenharmony_ci case RenderCommandType::GPU_QUEUE_TRANSFER_RELEASE: 7378bf80f4bSopenharmony_ci case RenderCommandType::GPU_QUEUE_TRANSFER_ACQUIRE: 7388bf80f4bSopenharmony_ci case RenderCommandType::UNDEFINED: 7398bf80f4bSopenharmony_ci default: { 7408bf80f4bSopenharmony_ci // nop 7418bf80f4bSopenharmony_ci break; 7428bf80f4bSopenharmony_ci } 7438bf80f4bSopenharmony_ci } 7448bf80f4bSopenharmony_ci } // end command for 7458bf80f4bSopenharmony_ci} 7468bf80f4bSopenharmony_ci 7478bf80f4bSopenharmony_civoid RenderGraph::StoreFinalBufferState() 7488bf80f4bSopenharmony_ci{ 7498bf80f4bSopenharmony_ci for (auto& ref : gpuBufferTracking_) { 7508bf80f4bSopenharmony_ci if (!RenderHandleUtil::IsDynamicResource(ref.resource.handle)) { 7518bf80f4bSopenharmony_ci ref = {}; 7528bf80f4bSopenharmony_ci continue; 7538bf80f4bSopenharmony_ci } 7548bf80f4bSopenharmony_ci if (RenderHandleUtil::IsResetOnFrameBorders(ref.resource.handle)) { 7558bf80f4bSopenharmony_ci // reset, but we do not reset the handle, because the gpuImageTracking_ element is not removed 7568bf80f4bSopenharmony_ci const RenderHandle handle = ref.resource.handle; 7578bf80f4bSopenharmony_ci ref = {}; 7588bf80f4bSopenharmony_ci ref.resource.handle = handle; 7598bf80f4bSopenharmony_ci } 7608bf80f4bSopenharmony_ci // need to reset per frame variables for all buffers (so we do not try to patch or debug from previous 7618bf80f4bSopenharmony_ci // frames) 7628bf80f4bSopenharmony_ci ref.prevRc = {}; 7638bf80f4bSopenharmony_ci ref.prevRenderNodeIndex = { ~0u }; 7648bf80f4bSopenharmony_ci } 7658bf80f4bSopenharmony_ci} 7668bf80f4bSopenharmony_ci 7678bf80f4bSopenharmony_civoid RenderGraph::StoreFinalImageState() 7688bf80f4bSopenharmony_ci{ 7698bf80f4bSopenharmony_ci swapchainStates_ = {}; // reset 7708bf80f4bSopenharmony_ci 7718bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 7728bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES) { 7738bf80f4bSopenharmony_ci PLUGIN_LOG_I("end_frame image_state:"); 7748bf80f4bSopenharmony_ci } 7758bf80f4bSopenharmony_ci#endif 7768bf80f4bSopenharmony_ci for (auto& ref : gpuImageTracking_) { 7778bf80f4bSopenharmony_ci // if resource is not dynamic, we do not track and care 7788bf80f4bSopenharmony_ci if (!RenderHandleUtil::IsDynamicResource(ref.resource.handle)) { 7798bf80f4bSopenharmony_ci ref = {}; 7808bf80f4bSopenharmony_ci continue; 7818bf80f4bSopenharmony_ci } 7828bf80f4bSopenharmony_ci // handle automatic presentation layout 7838bf80f4bSopenharmony_ci if (stateCache_.checkForBackbufferDependency && RenderHandleUtil::IsSwapchain(ref.resource.handle)) { 7848bf80f4bSopenharmony_ci if (ref.prevRc.type == RenderCommandType::BEGIN_RENDER_PASS) { 7858bf80f4bSopenharmony_ci RenderCommandBeginRenderPass& beginRenderPass = 7868bf80f4bSopenharmony_ci *static_cast<RenderCommandBeginRenderPass*>(ref.prevRc.rc); 7878bf80f4bSopenharmony_ci PatchRenderPassFinalLayout( 7888bf80f4bSopenharmony_ci ref.resource.handle, ImageLayout::CORE_IMAGE_LAYOUT_PRESENT_SRC, beginRenderPass, ref); 7898bf80f4bSopenharmony_ci } 7908bf80f4bSopenharmony_ci // NOTE: currently we handle automatic presentation layout in vulkan backend if not in render pass 7918bf80f4bSopenharmony_ci // store final state for backbuffer 7928bf80f4bSopenharmony_ci // currently we only swapchains if they are really in use in this frame 7938bf80f4bSopenharmony_ci const uint32_t flags = ref.state.accessFlags | ref.state.shaderStageFlags | ref.state.pipelineStageFlags; 7948bf80f4bSopenharmony_ci if (flags != 0) { 7958bf80f4bSopenharmony_ci swapchainStates_.swapchains.push_back({ ref.resource.handle, ref.state, ref.resource.imageLayout }); 7968bf80f4bSopenharmony_ci } 7978bf80f4bSopenharmony_ci } 7988bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 7998bf80f4bSopenharmony_ci // print before reset for next frame 8008bf80f4bSopenharmony_ci if constexpr (CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES) { 8018bf80f4bSopenharmony_ci DebugPrintImageState(gpuResourceMgr_, ref); 8028bf80f4bSopenharmony_ci } 8038bf80f4bSopenharmony_ci#endif 8048bf80f4bSopenharmony_ci // shallow resources are not tracked 8058bf80f4bSopenharmony_ci // they are always in undefined state in the beging of the frame 8068bf80f4bSopenharmony_ci if (RenderHandleUtil::IsResetOnFrameBorders(ref.resource.handle)) { 8078bf80f4bSopenharmony_ci const bool addMips = RenderHandleUtil::IsDynamicAdditionalStateResource(ref.resource.handle); 8088bf80f4bSopenharmony_ci // reset, but we do not reset the handle, because the gpuImageTracking_ element is not removed 8098bf80f4bSopenharmony_ci const RenderHandle handle = ref.resource.handle; 8108bf80f4bSopenharmony_ci ref = {}; 8118bf80f4bSopenharmony_ci ref.resource.handle = handle; 8128bf80f4bSopenharmony_ci if (addMips) { 8138bf80f4bSopenharmony_ci PLUGIN_ASSERT(!ref.additionalState.layouts); 8148bf80f4bSopenharmony_ci ref.additionalState.layouts = make_unique<ImageLayout[]>(MAX_MIP_STATE_COUNT); 8158bf80f4bSopenharmony_ci } 8168bf80f4bSopenharmony_ci } 8178bf80f4bSopenharmony_ci 8188bf80f4bSopenharmony_ci // need to reset per frame variables for all images (so we do not try to patch from previous frames) 8198bf80f4bSopenharmony_ci ref.prevRc = {}; 8208bf80f4bSopenharmony_ci ref.prevRenderNodeIndex = { ~0u }; 8218bf80f4bSopenharmony_ci } 8228bf80f4bSopenharmony_ci} 8238bf80f4bSopenharmony_ci 8248bf80f4bSopenharmony_civoid RenderGraph::RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 8258bf80f4bSopenharmony_ci RenderNodeContextData& nodeData, RenderCommandBeginRenderPass& rc, StateCache& stateCache) 8268bf80f4bSopenharmony_ci{ 8278bf80f4bSopenharmony_ci // update layouts for attachments to gpu image state 8288bf80f4bSopenharmony_ci BeginRenderPassParameters params { rc, stateCache, { RenderCommandType::BEGIN_RENDER_PASS, &rc } }; 8298bf80f4bSopenharmony_ci 8308bf80f4bSopenharmony_ci PLUGIN_ASSERT(rc.renderPassDesc.subpassCount > 0); 8318bf80f4bSopenharmony_ci 8328bf80f4bSopenharmony_ci const bool hasRenderPassDependency = stateCache.multiRenderPassStore.supportOpen; 8338bf80f4bSopenharmony_ci if (hasRenderPassDependency) { // stitch render pass subpasses 8348bf80f4bSopenharmony_ci BeginRenderPassHandleDependency(params, commandListCommandIndex, nodeData); 8358bf80f4bSopenharmony_ci } 8368bf80f4bSopenharmony_ci 8378bf80f4bSopenharmony_ci const GpuQueue gpuQueue = nodeData.renderCommandList->GetGpuQueue(); 8388bf80f4bSopenharmony_ci 8398bf80f4bSopenharmony_ci auto finalImageLayouts = 8408bf80f4bSopenharmony_ci array_view(rc.imageLayouts.attachmentFinalLayouts, countof(rc.imageLayouts.attachmentFinalLayouts)); 8418bf80f4bSopenharmony_ci 8428bf80f4bSopenharmony_ci BeginRenderPassUpdateImageStates(params, gpuQueue, finalImageLayouts, renderNodeIndex); 8438bf80f4bSopenharmony_ci 8448bf80f4bSopenharmony_ci for (uint32_t subpassIdx = 0; subpassIdx < rc.renderPassDesc.subpassCount; ++subpassIdx) { 8458bf80f4bSopenharmony_ci const auto& subpassRef = rc.subpasses[subpassIdx]; 8468bf80f4bSopenharmony_ci const auto& subpassResourceStatesRef = rc.subpassResourceStates[subpassIdx]; 8478bf80f4bSopenharmony_ci 8488bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates( 8498bf80f4bSopenharmony_ci array_view(subpassRef.inputAttachmentIndices, subpassRef.inputAttachmentCount), rc.renderPassDesc, 8508bf80f4bSopenharmony_ci subpassResourceStatesRef, finalImageLayouts, stateCache); 8518bf80f4bSopenharmony_ci 8528bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates( 8538bf80f4bSopenharmony_ci array_view(subpassRef.colorAttachmentIndices, subpassRef.colorAttachmentCount), rc.renderPassDesc, 8548bf80f4bSopenharmony_ci subpassResourceStatesRef, finalImageLayouts, stateCache); 8558bf80f4bSopenharmony_ci 8568bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates( 8578bf80f4bSopenharmony_ci array_view(subpassRef.resolveAttachmentIndices, subpassRef.resolveAttachmentCount), rc.renderPassDesc, 8588bf80f4bSopenharmony_ci subpassResourceStatesRef, finalImageLayouts, stateCache); 8598bf80f4bSopenharmony_ci 8608bf80f4bSopenharmony_ci if (subpassRef.depthAttachmentCount == 1u) { 8618bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates( 8628bf80f4bSopenharmony_ci array_view(&subpassRef.depthAttachmentIndex, subpassRef.depthAttachmentCount), rc.renderPassDesc, 8638bf80f4bSopenharmony_ci subpassResourceStatesRef, finalImageLayouts, stateCache); 8648bf80f4bSopenharmony_ci if (subpassRef.depthResolveAttachmentCount == 1) { 8658bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates( 8668bf80f4bSopenharmony_ci array_view(&subpassRef.depthResolveAttachmentIndex, subpassRef.depthResolveAttachmentCount), 8678bf80f4bSopenharmony_ci rc.renderPassDesc, subpassResourceStatesRef, finalImageLayouts, stateCache); 8688bf80f4bSopenharmony_ci } 8698bf80f4bSopenharmony_ci } 8708bf80f4bSopenharmony_ci if (subpassRef.fragmentShadingRateAttachmentCount == 1u) { 8718bf80f4bSopenharmony_ci BeginRenderPassUpdateSubpassImageStates(array_view(&subpassRef.fragmentShadingRateAttachmentIndex, 8728bf80f4bSopenharmony_ci subpassRef.fragmentShadingRateAttachmentCount), 8738bf80f4bSopenharmony_ci rc.renderPassDesc, subpassResourceStatesRef, finalImageLayouts, stateCache); 8748bf80f4bSopenharmony_ci } 8758bf80f4bSopenharmony_ci } 8768bf80f4bSopenharmony_ci 8778bf80f4bSopenharmony_ci if (hasRenderPassDependency) { // stitch render pass subpasses 8788bf80f4bSopenharmony_ci if (rc.subpassStartIndex > 0) { 8798bf80f4bSopenharmony_ci // stitched to behave as a nextSubpass() and not beginRenderPass() 8808bf80f4bSopenharmony_ci rc.beginType = RenderPassBeginType::RENDER_PASS_SUBPASS_BEGIN; 8818bf80f4bSopenharmony_ci } 8828bf80f4bSopenharmony_ci const bool finalSubpass = (rc.subpassStartIndex == rc.renderPassDesc.subpassCount - 1); 8838bf80f4bSopenharmony_ci if (finalSubpass) { 8848bf80f4bSopenharmony_ci UpdateMultiRenderCommandListRenderPasses(stateCache.multiRenderPassStore); 8858bf80f4bSopenharmony_ci // multiRenderPassStore cleared in EndRenderPass 8868bf80f4bSopenharmony_ci } 8878bf80f4bSopenharmony_ci } 8888bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 8898bf80f4bSopenharmony_ci if (CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES) { 8908bf80f4bSopenharmony_ci DebugRenderPassLayoutPrint(gpuResourceMgr_, rc); 8918bf80f4bSopenharmony_ci } 8928bf80f4bSopenharmony_ci#endif 8938bf80f4bSopenharmony_ci} 8948bf80f4bSopenharmony_ci 8958bf80f4bSopenharmony_civoid RenderGraph::BeginRenderPassHandleDependency( 8968bf80f4bSopenharmony_ci BeginRenderPassParameters& params, const uint32_t commandListCommandIndex, RenderNodeContextData& nodeData) 8978bf80f4bSopenharmony_ci{ 8988bf80f4bSopenharmony_ci params.stateCache.multiRenderPassStore.renderPasses.push_back(¶ms.rc); 8998bf80f4bSopenharmony_ci // store the first begin render pass 9008bf80f4bSopenharmony_ci params.rpForCmdRef = { RenderCommandType::BEGIN_RENDER_PASS, 9018bf80f4bSopenharmony_ci params.stateCache.multiRenderPassStore.renderPasses[0] }; 9028bf80f4bSopenharmony_ci 9038bf80f4bSopenharmony_ci if (params.rc.subpassStartIndex == 0) { // store the first render pass barrier point 9048bf80f4bSopenharmony_ci // barrier point must be previous command 9058bf80f4bSopenharmony_ci PLUGIN_ASSERT(commandListCommandIndex >= 1); 9068bf80f4bSopenharmony_ci const uint32_t prevCommandIndex = commandListCommandIndex - 1; 9078bf80f4bSopenharmony_ci 9088bf80f4bSopenharmony_ci const RenderCommandWithType& barrierPointCmdRef = 9098bf80f4bSopenharmony_ci nodeData.renderCommandList->GetRenderCommands()[prevCommandIndex]; 9108bf80f4bSopenharmony_ci PLUGIN_ASSERT(barrierPointCmdRef.type == RenderCommandType::BARRIER_POINT); 9118bf80f4bSopenharmony_ci PLUGIN_ASSERT(static_cast<RenderCommandBarrierPoint*>(barrierPointCmdRef.rc)); 9128bf80f4bSopenharmony_ci 9138bf80f4bSopenharmony_ci params.stateCache.multiRenderPassStore.firstRenderPassBarrierList = nodeData.renderBarrierList.get(); 9148bf80f4bSopenharmony_ci params.stateCache.multiRenderPassStore.firstBarrierPointIndex = 9158bf80f4bSopenharmony_ci static_cast<RenderCommandBarrierPoint*>(barrierPointCmdRef.rc)->barrierPointIndex; 9168bf80f4bSopenharmony_ci } 9178bf80f4bSopenharmony_ci} 9188bf80f4bSopenharmony_ci 9198bf80f4bSopenharmony_civoid RenderGraph::BeginRenderPassUpdateImageStates(BeginRenderPassParameters& params, const GpuQueue& gpuQueue, 9208bf80f4bSopenharmony_ci array_view<ImageLayout>& finalImageLayouts, const uint32_t renderNodeIndex) 9218bf80f4bSopenharmony_ci{ 9228bf80f4bSopenharmony_ci auto& initialImageLayouts = params.rc.imageLayouts.attachmentInitialLayouts; 9238bf80f4bSopenharmony_ci const auto& attachmentHandles = params.rc.renderPassDesc.attachmentHandles; 9248bf80f4bSopenharmony_ci auto& attachments = params.rc.renderPassDesc.attachments; 9258bf80f4bSopenharmony_ci auto& attachmentInputResourceStates = params.rc.inputResourceStates; 9268bf80f4bSopenharmony_ci 9278bf80f4bSopenharmony_ci for (uint32_t attachmentIdx = 0; attachmentIdx < params.rc.renderPassDesc.attachmentCount; ++attachmentIdx) { 9288bf80f4bSopenharmony_ci const RenderHandle handle = attachmentHandles[attachmentIdx]; 9298bf80f4bSopenharmony_ci // NOTE: invalidate invalid handle commands already in render command list 9308bf80f4bSopenharmony_ci if (!RenderHandleUtil::IsGpuImage(handle)) { 9318bf80f4bSopenharmony_ci#ifdef _DEBUG 9328bf80f4bSopenharmony_ci PLUGIN_LOG_E("invalid handle in render node graph"); 9338bf80f4bSopenharmony_ci#endif 9348bf80f4bSopenharmony_ci continue; 9358bf80f4bSopenharmony_ci } 9368bf80f4bSopenharmony_ci auto& stateRef = GetImageResourceStateRef(handle, gpuQueue); 9378bf80f4bSopenharmony_ci ImageLayout imgLayout = stateRef.resource.imageLayout; 9388bf80f4bSopenharmony_ci 9398bf80f4bSopenharmony_ci const bool addMips = RenderHandleUtil::IsDynamicAdditionalStateResource(handle); 9408bf80f4bSopenharmony_ci // image layout is undefined if automatic barriers have been disabled 9418bf80f4bSopenharmony_ci if (params.rc.enableAutomaticLayoutChanges) { 9428bf80f4bSopenharmony_ci const RenderPassDesc::AttachmentDesc& attachmentDesc = attachments[attachmentIdx]; 9438bf80f4bSopenharmony_ci if (addMips && (attachmentDesc.mipLevel < RenderGraph::MAX_MIP_STATE_COUNT)) { 9448bf80f4bSopenharmony_ci if (stateRef.additionalState.layouts) { 9458bf80f4bSopenharmony_ci imgLayout = stateRef.additionalState.layouts[attachmentDesc.mipLevel]; 9468bf80f4bSopenharmony_ci } else { 9478bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 9488bf80f4bSopenharmony_ci PLUGIN_LOG_ONCE_E(to_hex(handle.id), "mip layouts missing"); 9498bf80f4bSopenharmony_ci#endif 9508bf80f4bSopenharmony_ci } 9518bf80f4bSopenharmony_ci } 9528bf80f4bSopenharmony_ci 9538bf80f4bSopenharmony_ci initialImageLayouts[attachmentIdx] = imgLayout; 9548bf80f4bSopenharmony_ci } 9558bf80f4bSopenharmony_ci // undefined layout with load_op_load -> we modify to dont_care (and remove validation warning) 9568bf80f4bSopenharmony_ci if ((imgLayout == ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED) && 9578bf80f4bSopenharmony_ci (attachments[attachmentIdx].loadOp == AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_LOAD)) { 9588bf80f4bSopenharmony_ci // dont care (user needs to be sure what is wanted, i.e. in first frame one should clear) 9598bf80f4bSopenharmony_ci attachments[attachmentIdx].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE; 9608bf80f4bSopenharmony_ci } 9618bf80f4bSopenharmony_ci finalImageLayouts[attachmentIdx] = imgLayout; 9628bf80f4bSopenharmony_ci attachmentInputResourceStates.states[attachmentIdx] = stateRef.state; 9638bf80f4bSopenharmony_ci attachmentInputResourceStates.layouts[attachmentIdx] = imgLayout; 9648bf80f4bSopenharmony_ci 9658bf80f4bSopenharmony_ci // store render pass for final layout patching 9668bf80f4bSopenharmony_ci stateRef.prevRc = params.rpForCmdRef; 9678bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex = renderNodeIndex; 9688bf80f4bSopenharmony_ci 9698bf80f4bSopenharmony_ci // flag for backbuffer use 9708bf80f4bSopenharmony_ci if (params.stateCache.checkForBackbufferDependency && RenderHandleUtil::IsSwapchain(handle)) { 9718bf80f4bSopenharmony_ci params.stateCache.usesSwapchainImage = true; 9728bf80f4bSopenharmony_ci } 9738bf80f4bSopenharmony_ci } 9748bf80f4bSopenharmony_ci} 9758bf80f4bSopenharmony_ci 9768bf80f4bSopenharmony_civoid RenderGraph::BeginRenderPassUpdateSubpassImageStates(array_view<const uint32_t> attatchmentIndices, 9778bf80f4bSopenharmony_ci const RenderPassDesc& renderPassDesc, const RenderPassAttachmentResourceStates& subpassResourceStatesRef, 9788bf80f4bSopenharmony_ci array_view<ImageLayout> finalImageLayouts, StateCache& stateCache) 9798bf80f4bSopenharmony_ci{ 9808bf80f4bSopenharmony_ci for (const uint32_t attachmentIndex : attatchmentIndices) { 9818bf80f4bSopenharmony_ci // NOTE: handle invalid commands already in render command list and invalidate draws etc. 9828bf80f4bSopenharmony_ci PLUGIN_ASSERT(attachmentIndex < renderPassDesc.attachmentCount); 9838bf80f4bSopenharmony_ci const RenderHandle handle = renderPassDesc.attachmentHandles[attachmentIndex]; 9848bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_IMAGE); 9858bf80f4bSopenharmony_ci const GpuResourceState& refState = subpassResourceStatesRef.states[attachmentIndex]; 9868bf80f4bSopenharmony_ci const ImageLayout& refImgLayout = subpassResourceStatesRef.layouts[attachmentIndex]; 9878bf80f4bSopenharmony_ci // NOTE: we should support non dynamicity and GENERAL 9888bf80f4bSopenharmony_ci 9898bf80f4bSopenharmony_ci finalImageLayouts[attachmentIndex] = refImgLayout; 9908bf80f4bSopenharmony_ci auto& ref = GetImageResourceStateRef(handle, refState.gpuQueue); 9918bf80f4bSopenharmony_ci const bool addMips = RenderHandleUtil::IsDynamicAdditionalStateResource(handle); 9928bf80f4bSopenharmony_ci 9938bf80f4bSopenharmony_ci ref.state = refState; 9948bf80f4bSopenharmony_ci ref.resource.handle = handle; 9958bf80f4bSopenharmony_ci ref.resource.imageLayout = refImgLayout; 9968bf80f4bSopenharmony_ci if (addMips) { 9978bf80f4bSopenharmony_ci const RenderPassDesc::AttachmentDesc& attachmentDesc = renderPassDesc.attachments[attachmentIndex]; 9988bf80f4bSopenharmony_ci const BindableImage image { 9998bf80f4bSopenharmony_ci handle, 10008bf80f4bSopenharmony_ci attachmentDesc.mipLevel, 10018bf80f4bSopenharmony_ci attachmentDesc.layer, 10028bf80f4bSopenharmony_ci refImgLayout, 10038bf80f4bSopenharmony_ci RenderHandle {}, 10048bf80f4bSopenharmony_ci }; 10058bf80f4bSopenharmony_ci ModifyAdditionalImageState(image, ref.additionalState); 10068bf80f4bSopenharmony_ci } 10078bf80f4bSopenharmony_ci } 10088bf80f4bSopenharmony_ci} 10098bf80f4bSopenharmony_ci 10108bf80f4bSopenharmony_civoid RenderGraph::RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 10118bf80f4bSopenharmony_ci const RenderNodeContextData& nodeData, RenderCommandEndRenderPass& rc, StateCache& stateCache) 10128bf80f4bSopenharmony_ci{ 10138bf80f4bSopenharmony_ci const bool hasRenderPassDependency = stateCache.multiRenderPassStore.supportOpen; 10148bf80f4bSopenharmony_ci if (hasRenderPassDependency) { 10158bf80f4bSopenharmony_ci const bool finalSubpass = (rc.subpassCount == (uint32_t)stateCache.multiRenderPassStore.renderPasses.size()); 10168bf80f4bSopenharmony_ci if (finalSubpass) { 10178bf80f4bSopenharmony_ci if (rc.subpassStartIndex != (rc.subpassCount - 1)) { 10188bf80f4bSopenharmony_ci PLUGIN_LOG_E("RenderGraph: error in multi render node render pass subpass ending"); 10198bf80f4bSopenharmony_ci // NOTE: add more error handling and invalidate render command lists 10208bf80f4bSopenharmony_ci } 10218bf80f4bSopenharmony_ci rc.endType = RenderPassEndType::END_RENDER_PASS; 10228bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.renderPasses.clear(); 10238bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.firstRenderPassBarrierList = nullptr; 10248bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.firstBarrierPointIndex = ~0u; 10258bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.supportOpen = false; 10268bf80f4bSopenharmony_ci } else { 10278bf80f4bSopenharmony_ci rc.endType = RenderPassEndType::END_SUBPASS; 10288bf80f4bSopenharmony_ci } 10298bf80f4bSopenharmony_ci } 10308bf80f4bSopenharmony_ci} 10318bf80f4bSopenharmony_ci 10328bf80f4bSopenharmony_civoid RenderGraph::RenderCommand(const uint32_t renderNodeIndex, const uint32_t commandListCommandIndex, 10338bf80f4bSopenharmony_ci RenderNodeContextData& nodeData, RenderCommandBarrierPoint& rc, StateCache& stateCache) 10348bf80f4bSopenharmony_ci{ 10358bf80f4bSopenharmony_ci // go through required descriptors for current upcoming event 10368bf80f4bSopenharmony_ci const auto& customBarrierListRef = nodeData.renderCommandList->GetCustomBarriers(); 10378bf80f4bSopenharmony_ci const auto& cmdListRef = nodeData.renderCommandList->GetRenderCommands(); 10388bf80f4bSopenharmony_ci const auto& allDescriptorSetHandlesForBarriers = nodeData.renderCommandList->GetDescriptorSetHandles(); 10398bf80f4bSopenharmony_ci const auto& nodeDescriptorSetMgrRef = *nodeData.nodeContextDescriptorSetMgr; 10408bf80f4bSopenharmony_ci 10418bf80f4bSopenharmony_ci parameterCachePools_.combinedBarriers.clear(); 10428bf80f4bSopenharmony_ci parameterCachePools_.handledCustomBarriers.clear(); 10438bf80f4bSopenharmony_ci ParameterCache parameters { parameterCachePools_.combinedBarriers, parameterCachePools_.handledCustomBarriers, 10448bf80f4bSopenharmony_ci rc.customBarrierCount, rc.vertexIndexBarrierCount, rc.indirectBufferBarrierCount, renderNodeIndex, 10458bf80f4bSopenharmony_ci nodeData.renderCommandList->GetGpuQueue(), { RenderCommandType::BARRIER_POINT, &rc }, stateCache }; 10468bf80f4bSopenharmony_ci // first check custom barriers 10478bf80f4bSopenharmony_ci if (parameters.customBarrierCount > 0) { 10488bf80f4bSopenharmony_ci HandleCustomBarriers(parameters, rc.customBarrierIndexBegin, customBarrierListRef); 10498bf80f4bSopenharmony_ci } 10508bf80f4bSopenharmony_ci // then vertex / index buffer barriers in the barrier point before render pass 10518bf80f4bSopenharmony_ci if (parameters.vertexInputBarrierCount > 0) { 10528bf80f4bSopenharmony_ci PLUGIN_ASSERT(rc.renderCommandType == RenderCommandType::BEGIN_RENDER_PASS); 10538bf80f4bSopenharmony_ci HandleVertexInputBufferBarriers(parameters, rc.vertexIndexBarrierIndexBegin, 10548bf80f4bSopenharmony_ci nodeData.renderCommandList->GetRenderpassVertexInputBufferBarriers()); 10558bf80f4bSopenharmony_ci } 10568bf80f4bSopenharmony_ci if (parameters.indirectBufferBarrierCount > 0U) { 10578bf80f4bSopenharmony_ci PLUGIN_ASSERT(rc.renderCommandType == RenderCommandType::BEGIN_RENDER_PASS); 10588bf80f4bSopenharmony_ci HandleRenderpassIndirectBufferBarriers(parameters, rc.indirectBufferBarrierIndexBegin, 10598bf80f4bSopenharmony_ci nodeData.renderCommandList->GetRenderpassIndirectBufferBarriers()); 10608bf80f4bSopenharmony_ci } 10618bf80f4bSopenharmony_ci 10628bf80f4bSopenharmony_ci // in barrier point the next render command is known for which the barrier is needed 10638bf80f4bSopenharmony_ci if (rc.renderCommandType == RenderCommandType::CLEAR_COLOR_IMAGE) { 10648bf80f4bSopenharmony_ci HandleClearImage(parameters, commandListCommandIndex, cmdListRef); 10658bf80f4bSopenharmony_ci } else if (rc.renderCommandType == RenderCommandType::BLIT_IMAGE) { 10668bf80f4bSopenharmony_ci HandleBlitImage(parameters, commandListCommandIndex, cmdListRef); 10678bf80f4bSopenharmony_ci } else if (rc.renderCommandType == RenderCommandType::COPY_BUFFER) { 10688bf80f4bSopenharmony_ci HandleCopyBuffer(parameters, commandListCommandIndex, cmdListRef); 10698bf80f4bSopenharmony_ci } else if (rc.renderCommandType == RenderCommandType::COPY_BUFFER_IMAGE) { 10708bf80f4bSopenharmony_ci HandleCopyBufferImage(parameters, commandListCommandIndex, cmdListRef); 10718bf80f4bSopenharmony_ci } else if (rc.renderCommandType == RenderCommandType::COPY_IMAGE) { 10728bf80f4bSopenharmony_ci HandleCopyBufferImage(parameters, commandListCommandIndex, cmdListRef); // NOTE: handles image to image 10738bf80f4bSopenharmony_ci } else { // descriptor sets 10748bf80f4bSopenharmony_ci if (rc.renderCommandType == RenderCommandType::DISPATCH_INDIRECT) { 10758bf80f4bSopenharmony_ci HandleDispatchIndirect(parameters, commandListCommandIndex, cmdListRef); 10768bf80f4bSopenharmony_ci } 10778bf80f4bSopenharmony_ci const uint32_t descriptorSetHandleBeginIndex = rc.descriptorSetHandleIndexBegin; 10788bf80f4bSopenharmony_ci const uint32_t descriptorSetHandleEndIndex = descriptorSetHandleBeginIndex + rc.descriptorSetHandleCount; 10798bf80f4bSopenharmony_ci const uint32_t descriptorSetHandleMaxIndex = 10808bf80f4bSopenharmony_ci Math::min(descriptorSetHandleEndIndex, static_cast<uint32_t>(allDescriptorSetHandlesForBarriers.size())); 10818bf80f4bSopenharmony_ci const auto descriptorSetHandlesForBarriers = 10828bf80f4bSopenharmony_ci array_view(allDescriptorSetHandlesForBarriers.data() + descriptorSetHandleBeginIndex, 10838bf80f4bSopenharmony_ci allDescriptorSetHandlesForBarriers.data() + descriptorSetHandleMaxIndex); 10848bf80f4bSopenharmony_ci HandleDescriptorSets(parameters, descriptorSetHandlesForBarriers, nodeDescriptorSetMgrRef); 10858bf80f4bSopenharmony_ci } 10868bf80f4bSopenharmony_ci 10878bf80f4bSopenharmony_ci if (!parameters.combinedBarriers.empty()) { 10888bf80f4bSopenharmony_ci // use first render pass barrier point with following subpasses 10898bf80f4bSopenharmony_ci // firstRenderPassBarrierPoint is null for the first subpass 10908bf80f4bSopenharmony_ci const bool renderPassHasDependancy = stateCache.multiRenderPassStore.supportOpen; 10918bf80f4bSopenharmony_ci if (renderPassHasDependancy && stateCache.multiRenderPassStore.firstRenderPassBarrierList) { 10928bf80f4bSopenharmony_ci PLUGIN_ASSERT(!stateCache.multiRenderPassStore.renderPasses.empty()); 10938bf80f4bSopenharmony_ci stateCache.multiRenderPassStore.firstRenderPassBarrierList->AddBarriersToBarrierPoint( 10948bf80f4bSopenharmony_ci rc.barrierPointIndex, parameters.combinedBarriers); 10958bf80f4bSopenharmony_ci } else { 10968bf80f4bSopenharmony_ci nodeData.renderBarrierList->AddBarriersToBarrierPoint(rc.barrierPointIndex, parameters.combinedBarriers); 10978bf80f4bSopenharmony_ci } 10988bf80f4bSopenharmony_ci } 10998bf80f4bSopenharmony_ci#if (RENDER_DEV_ENABLED == 1) 11008bf80f4bSopenharmony_ci if (CORE_RENDER_GRAPH_PRINT_RESOURCE_STATES) { 11018bf80f4bSopenharmony_ci DebugBarrierPrint(gpuResourceMgr_, parameters.combinedBarriers); 11028bf80f4bSopenharmony_ci } 11038bf80f4bSopenharmony_ci#endif 11048bf80f4bSopenharmony_ci} 11058bf80f4bSopenharmony_ci 11068bf80f4bSopenharmony_ciinline void RenderGraph::UpdateBufferResourceState( 11078bf80f4bSopenharmony_ci RenderGraphBufferState& stateRef, const ParameterCache& params, const CommandBarrier& cb) 11088bf80f4bSopenharmony_ci{ 11098bf80f4bSopenharmony_ci stateRef.resource.handle = cb.resourceHandle; 11108bf80f4bSopenharmony_ci stateRef.state.shaderStageFlags = 0; 11118bf80f4bSopenharmony_ci stateRef.state.accessFlags = cb.dst.accessFlags; 11128bf80f4bSopenharmony_ci stateRef.state.pipelineStageFlags = cb.dst.pipelineStageFlags; 11138bf80f4bSopenharmony_ci stateRef.state.gpuQueue = params.gpuQueue; 11148bf80f4bSopenharmony_ci stateRef.prevRc = params.rcWithType; 11158bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex = params.renderNodeIndex; 11168bf80f4bSopenharmony_ci} 11178bf80f4bSopenharmony_ci 11188bf80f4bSopenharmony_ciinline void RenderGraph::UpdateImageResourceState( 11198bf80f4bSopenharmony_ci RenderGraphImageState& stateRef, const ParameterCache& params, const CommandBarrier& cb) 11208bf80f4bSopenharmony_ci{ 11218bf80f4bSopenharmony_ci stateRef.resource.handle = cb.resourceHandle; 11228bf80f4bSopenharmony_ci stateRef.state.shaderStageFlags = 0; 11238bf80f4bSopenharmony_ci stateRef.state.accessFlags = cb.dst.accessFlags; 11248bf80f4bSopenharmony_ci stateRef.state.pipelineStageFlags = cb.dst.pipelineStageFlags; 11258bf80f4bSopenharmony_ci stateRef.state.gpuQueue = params.gpuQueue; 11268bf80f4bSopenharmony_ci stateRef.prevRc = params.rcWithType; 11278bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex = params.renderNodeIndex; 11288bf80f4bSopenharmony_ci} 11298bf80f4bSopenharmony_ci 11308bf80f4bSopenharmony_civoid RenderGraph::HandleCustomBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 11318bf80f4bSopenharmony_ci const array_view<const CommandBarrier>& customBarrierListRef) 11328bf80f4bSopenharmony_ci{ 11338bf80f4bSopenharmony_ci params.handledCustomBarriers.reserve(params.customBarrierCount); 11348bf80f4bSopenharmony_ci PLUGIN_ASSERT(barrierIndexBegin + params.customBarrierCount <= customBarrierListRef.size()); 11358bf80f4bSopenharmony_ci for (auto begin = (customBarrierListRef.begin() + barrierIndexBegin), 11368bf80f4bSopenharmony_ci end = Math::min(customBarrierListRef.end(), begin + params.customBarrierCount); 11378bf80f4bSopenharmony_ci begin != end; ++begin) { 11388bf80f4bSopenharmony_ci // add a copy and modify if needed 11398bf80f4bSopenharmony_ci auto& cb = params.combinedBarriers.emplace_back(*begin); 11408bf80f4bSopenharmony_ci 11418bf80f4bSopenharmony_ci // NOTE: undefined type is for non-resource memory/pipeline barriers 11428bf80f4bSopenharmony_ci const RenderHandleType type = RenderHandleUtil::GetHandleType(cb.resourceHandle); 11438bf80f4bSopenharmony_ci const bool isDynamicTrack = RenderHandleUtil::IsDynamicResource(cb.resourceHandle); 11448bf80f4bSopenharmony_ci PLUGIN_ASSERT((type == RenderHandleType::UNDEFINED) || (type == RenderHandleType::GPU_BUFFER) || 11458bf80f4bSopenharmony_ci (type == RenderHandleType::GPU_IMAGE)); 11468bf80f4bSopenharmony_ci if (type == RenderHandleType::GPU_BUFFER) { 11478bf80f4bSopenharmony_ci if (isDynamicTrack) { 11488bf80f4bSopenharmony_ci auto& stateRef = GetBufferResourceStateRef(cb.resourceHandle, params.gpuQueue); 11498bf80f4bSopenharmony_ci UpdateBufferResourceState(stateRef, params, cb); 11508bf80f4bSopenharmony_ci } 11518bf80f4bSopenharmony_ci params.handledCustomBarriers[cb.resourceHandle] = 0; 11528bf80f4bSopenharmony_ci } else if (type == RenderHandleType::GPU_IMAGE) { 11538bf80f4bSopenharmony_ci if (isDynamicTrack) { 11548bf80f4bSopenharmony_ci const bool isAddMips = RenderHandleUtil::IsDynamicAdditionalStateResource(cb.resourceHandle); 11558bf80f4bSopenharmony_ci auto& stateRef = GetImageResourceStateRef(cb.resourceHandle, params.gpuQueue); 11568bf80f4bSopenharmony_ci if (cb.src.optionalImageLayout == CORE_IMAGE_LAYOUT_MAX_ENUM) { 11578bf80f4bSopenharmony_ci uint32_t mipLevel = 0U; 11588bf80f4bSopenharmony_ci uint32_t mipCount = PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS; 11598bf80f4bSopenharmony_ci ImageLayout srcImageLayout = stateRef.resource.imageLayout; 11608bf80f4bSopenharmony_ci if (isAddMips) { 11618bf80f4bSopenharmony_ci const uint32_t srcMip = cb.src.optionalImageSubresourceRange.baseMipLevel; 11628bf80f4bSopenharmony_ci const uint32_t dstMip = cb.dst.optionalImageSubresourceRange.baseMipLevel; 11638bf80f4bSopenharmony_ci if ((srcMip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS) || 11648bf80f4bSopenharmony_ci (dstMip != PipelineStateConstants::GPU_IMAGE_ALL_MIP_LEVELS)) { 11658bf80f4bSopenharmony_ci if (dstMip < RenderGraph::MAX_MIP_STATE_COUNT) { 11668bf80f4bSopenharmony_ci mipLevel = dstMip; 11678bf80f4bSopenharmony_ci mipCount = 1U; 11688bf80f4bSopenharmony_ci } else { 11698bf80f4bSopenharmony_ci mipLevel = srcMip; 11708bf80f4bSopenharmony_ci // all mip levels 11718bf80f4bSopenharmony_ci } 11728bf80f4bSopenharmony_ci if (stateRef.additionalState.layouts) { 11738bf80f4bSopenharmony_ci srcImageLayout = stateRef.additionalState.layouts[mipLevel]; 11748bf80f4bSopenharmony_ci } else { 11758bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 11768bf80f4bSopenharmony_ci PLUGIN_LOG_ONCE_E(to_hex(cb.resourceHandle.id), "mip layouts missing"); 11778bf80f4bSopenharmony_ci#endif 11788bf80f4bSopenharmony_ci } 11798bf80f4bSopenharmony_ci } 11808bf80f4bSopenharmony_ci } 11818bf80f4bSopenharmony_ci cb.src.accessFlags = stateRef.state.accessFlags; 11828bf80f4bSopenharmony_ci cb.src.pipelineStageFlags = 11838bf80f4bSopenharmony_ci stateRef.state.pipelineStageFlags | PipelineStageFlagBits::CORE_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 11848bf80f4bSopenharmony_ci cb.src.optionalImageLayout = srcImageLayout; 11858bf80f4bSopenharmony_ci cb.src.optionalImageSubresourceRange = { 0, mipLevel, mipCount, 0u, 11868bf80f4bSopenharmony_ci PipelineStateConstants::GPU_IMAGE_ALL_LAYERS }; 11878bf80f4bSopenharmony_ci } 11888bf80f4bSopenharmony_ci UpdateImageResourceState(stateRef, params, cb); 11898bf80f4bSopenharmony_ci stateRef.resource.imageLayout = cb.dst.optionalImageLayout; 11908bf80f4bSopenharmony_ci if (isAddMips) { 11918bf80f4bSopenharmony_ci const BindableImage image { 11928bf80f4bSopenharmony_ci cb.resourceHandle, 11938bf80f4bSopenharmony_ci cb.dst.optionalImageSubresourceRange.baseMipLevel, 11948bf80f4bSopenharmony_ci cb.dst.optionalImageSubresourceRange.baseArrayLayer, 11958bf80f4bSopenharmony_ci cb.dst.optionalImageLayout, 11968bf80f4bSopenharmony_ci RenderHandle {}, 11978bf80f4bSopenharmony_ci }; 11988bf80f4bSopenharmony_ci ModifyAdditionalImageState(image, stateRef.additionalState); 11998bf80f4bSopenharmony_ci } 12008bf80f4bSopenharmony_ci } 12018bf80f4bSopenharmony_ci params.handledCustomBarriers[cb.resourceHandle] = 0; 12028bf80f4bSopenharmony_ci } 12038bf80f4bSopenharmony_ci } 12048bf80f4bSopenharmony_ci} 12058bf80f4bSopenharmony_ci 12068bf80f4bSopenharmony_civoid RenderGraph::HandleVertexInputBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 12078bf80f4bSopenharmony_ci const array_view<const VertexBuffer>& vertexInputBufferBarrierListRef) 12088bf80f4bSopenharmony_ci{ 12098bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < params.vertexInputBarrierCount; ++idx) { 12108bf80f4bSopenharmony_ci const uint32_t barrierIndex = barrierIndexBegin + idx; 12118bf80f4bSopenharmony_ci PLUGIN_ASSERT(barrierIndex < (uint32_t)vertexInputBufferBarrierListRef.size()); 12128bf80f4bSopenharmony_ci if (barrierIndex < (uint32_t)vertexInputBufferBarrierListRef.size()) { 12138bf80f4bSopenharmony_ci const VertexBuffer& vbInput = vertexInputBufferBarrierListRef[barrierIndex]; 12148bf80f4bSopenharmony_ci const GpuResourceState resourceState { CORE_SHADER_STAGE_VERTEX_BIT, 12158bf80f4bSopenharmony_ci CORE_ACCESS_INDEX_READ_BIT | CORE_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, 12168bf80f4bSopenharmony_ci CORE_PIPELINE_STAGE_VERTEX_INPUT_BIT, params.gpuQueue }; 12178bf80f4bSopenharmony_ci UpdateStateAndCreateBarriersGpuBuffer( 12188bf80f4bSopenharmony_ci resourceState, { vbInput.bufferHandle, vbInput.bufferOffset, vbInput.byteSize }, params); 12198bf80f4bSopenharmony_ci } 12208bf80f4bSopenharmony_ci } 12218bf80f4bSopenharmony_ci} 12228bf80f4bSopenharmony_ci 12238bf80f4bSopenharmony_civoid RenderGraph::HandleRenderpassIndirectBufferBarriers(ParameterCache& params, const uint32_t barrierIndexBegin, 12248bf80f4bSopenharmony_ci const array_view<const VertexBuffer>& indirectBufferBarrierListRef) 12258bf80f4bSopenharmony_ci{ 12268bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < params.indirectBufferBarrierCount; ++idx) { 12278bf80f4bSopenharmony_ci const uint32_t barrierIndex = barrierIndexBegin + idx; 12288bf80f4bSopenharmony_ci PLUGIN_ASSERT(barrierIndex < (uint32_t)indirectBufferBarrierListRef.size()); 12298bf80f4bSopenharmony_ci if (barrierIndex < (uint32_t)indirectBufferBarrierListRef.size()) { 12308bf80f4bSopenharmony_ci const VertexBuffer& ib = indirectBufferBarrierListRef[barrierIndex]; 12318bf80f4bSopenharmony_ci const bool needsArgsBarrier = 12328bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, ib.bufferHandle); 12338bf80f4bSopenharmony_ci if (needsArgsBarrier) { 12348bf80f4bSopenharmony_ci const GpuResourceState resourceState { CORE_SHADER_STAGE_VERTEX_BIT, 12358bf80f4bSopenharmony_ci CORE_ACCESS_INDIRECT_COMMAND_READ_BIT, CORE_PIPELINE_STAGE_DRAW_INDIRECT_BIT, params.gpuQueue }; 12368bf80f4bSopenharmony_ci UpdateStateAndCreateBarriersGpuBuffer( 12378bf80f4bSopenharmony_ci resourceState, { ib.bufferHandle, ib.bufferOffset, ib.byteSize }, params); 12388bf80f4bSopenharmony_ci } 12398bf80f4bSopenharmony_ci } 12408bf80f4bSopenharmony_ci } 12418bf80f4bSopenharmony_ci} 12428bf80f4bSopenharmony_ci 12438bf80f4bSopenharmony_civoid RenderGraph::HandleClearImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 12448bf80f4bSopenharmony_ci const array_view<const RenderCommandWithType>& cmdListRef) 12458bf80f4bSopenharmony_ci{ 12468bf80f4bSopenharmony_ci const uint32_t nextListIdx = commandListCommandIndex + 1; 12478bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextListIdx < cmdListRef.size()); 12488bf80f4bSopenharmony_ci const auto& nextCmdRef = cmdListRef[nextListIdx]; 12498bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextCmdRef.type == RenderCommandType::CLEAR_COLOR_IMAGE); 12508bf80f4bSopenharmony_ci 12518bf80f4bSopenharmony_ci const RenderCommandClearColorImage& nextRc = *static_cast<RenderCommandClearColorImage*>(nextCmdRef.rc); 12528bf80f4bSopenharmony_ci 12538bf80f4bSopenharmony_ci const bool needsBarrier = 12548bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.handle); 12558bf80f4bSopenharmony_ci if (needsBarrier) { 12568bf80f4bSopenharmony_ci BindableImage bRes = {}; 12578bf80f4bSopenharmony_ci bRes.handle = nextRc.handle; 12588bf80f4bSopenharmony_ci bRes.imageLayout = nextRc.imageLayout; 12598bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheImage(params.renderNodeIndex, 12608bf80f4bSopenharmony_ci GpuResourceState { 0, CORE_ACCESS_TRANSFER_WRITE_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 12618bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 12628bf80f4bSopenharmony_ci } 12638bf80f4bSopenharmony_ci} 12648bf80f4bSopenharmony_ci 12658bf80f4bSopenharmony_civoid RenderGraph::HandleBlitImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 12668bf80f4bSopenharmony_ci const array_view<const RenderCommandWithType>& cmdListRef) 12678bf80f4bSopenharmony_ci{ 12688bf80f4bSopenharmony_ci const uint32_t nextListIdx = commandListCommandIndex + 1; 12698bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextListIdx < cmdListRef.size()); 12708bf80f4bSopenharmony_ci const auto& nextCmdRef = cmdListRef[nextListIdx]; 12718bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextCmdRef.type == RenderCommandType::BLIT_IMAGE); 12728bf80f4bSopenharmony_ci 12738bf80f4bSopenharmony_ci const RenderCommandBlitImage& nextRc = *static_cast<RenderCommandBlitImage*>(nextCmdRef.rc); 12748bf80f4bSopenharmony_ci 12758bf80f4bSopenharmony_ci const bool needsSrcBarrier = 12768bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.srcHandle); 12778bf80f4bSopenharmony_ci if (needsSrcBarrier) { 12788bf80f4bSopenharmony_ci BindableImage bRes = {}; 12798bf80f4bSopenharmony_ci bRes.handle = nextRc.srcHandle; 12808bf80f4bSopenharmony_ci bRes.imageLayout = nextRc.srcImageLayout; 12818bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheImage(params.renderNodeIndex, 12828bf80f4bSopenharmony_ci GpuResourceState { 0, CORE_ACCESS_TRANSFER_READ_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 12838bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 12848bf80f4bSopenharmony_ci } 12858bf80f4bSopenharmony_ci 12868bf80f4bSopenharmony_ci const bool needsDstBarrier = 12878bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.dstHandle); 12888bf80f4bSopenharmony_ci if (needsDstBarrier) { 12898bf80f4bSopenharmony_ci BindableImage bRes = {}; 12908bf80f4bSopenharmony_ci bRes.handle = nextRc.dstHandle; 12918bf80f4bSopenharmony_ci bRes.imageLayout = nextRc.dstImageLayout; 12928bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheImage(params.renderNodeIndex, 12938bf80f4bSopenharmony_ci GpuResourceState { 0, CORE_ACCESS_TRANSFER_WRITE_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 12948bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 12958bf80f4bSopenharmony_ci } 12968bf80f4bSopenharmony_ci} 12978bf80f4bSopenharmony_ci 12988bf80f4bSopenharmony_civoid RenderGraph::HandleCopyBuffer(ParameterCache& params, const uint32_t& commandListCommandIndex, 12998bf80f4bSopenharmony_ci const array_view<const RenderCommandWithType>& cmdListRef) 13008bf80f4bSopenharmony_ci{ 13018bf80f4bSopenharmony_ci const uint32_t nextListIdx = commandListCommandIndex + 1; 13028bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextListIdx < cmdListRef.size()); 13038bf80f4bSopenharmony_ci const auto& nextCmdRef = cmdListRef[nextListIdx]; 13048bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextCmdRef.type == RenderCommandType::COPY_BUFFER); 13058bf80f4bSopenharmony_ci 13068bf80f4bSopenharmony_ci const RenderCommandCopyBuffer& nextRc = *static_cast<RenderCommandCopyBuffer*>(nextCmdRef.rc); 13078bf80f4bSopenharmony_ci 13088bf80f4bSopenharmony_ci const bool needsSrcBarrier = 13098bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.srcHandle); 13108bf80f4bSopenharmony_ci if (needsSrcBarrier) { 13118bf80f4bSopenharmony_ci const BindableBuffer bRes = { nextRc.srcHandle, nextRc.bufferCopy.srcOffset, nextRc.bufferCopy.size }; 13128bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheBuffer(params.renderNodeIndex, 13138bf80f4bSopenharmony_ci GpuResourceState { 0, CORE_ACCESS_TRANSFER_READ_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 13148bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 13158bf80f4bSopenharmony_ci } 13168bf80f4bSopenharmony_ci 13178bf80f4bSopenharmony_ci const bool needsDstBarrier = 13188bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.dstHandle); 13198bf80f4bSopenharmony_ci if (needsDstBarrier) { 13208bf80f4bSopenharmony_ci const BindableBuffer bRes = { nextRc.dstHandle, nextRc.bufferCopy.dstOffset, nextRc.bufferCopy.size }; 13218bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheBuffer(params.renderNodeIndex, 13228bf80f4bSopenharmony_ci GpuResourceState { 0, CORE_ACCESS_TRANSFER_WRITE_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 13238bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 13248bf80f4bSopenharmony_ci } 13258bf80f4bSopenharmony_ci} 13268bf80f4bSopenharmony_ci 13278bf80f4bSopenharmony_civoid RenderGraph::HandleCopyBufferImage(ParameterCache& params, const uint32_t& commandListCommandIndex, 13288bf80f4bSopenharmony_ci const array_view<const RenderCommandWithType>& cmdListRef) 13298bf80f4bSopenharmony_ci{ 13308bf80f4bSopenharmony_ci const uint32_t nextListIdx = commandListCommandIndex + 1; 13318bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextListIdx < cmdListRef.size()); 13328bf80f4bSopenharmony_ci const auto& nextCmdRef = cmdListRef[nextListIdx]; 13338bf80f4bSopenharmony_ci PLUGIN_ASSERT((nextCmdRef.type == RenderCommandType::COPY_BUFFER_IMAGE) || 13348bf80f4bSopenharmony_ci (nextCmdRef.type == RenderCommandType::COPY_IMAGE)); 13358bf80f4bSopenharmony_ci 13368bf80f4bSopenharmony_ci // NOTE: two different command types supported 13378bf80f4bSopenharmony_ci RenderHandle srcHandle; 13388bf80f4bSopenharmony_ci RenderHandle dstHandle; 13398bf80f4bSopenharmony_ci ImageSubresourceLayers srcImgLayers; 13408bf80f4bSopenharmony_ci ImageSubresourceLayers dstImgLayers; 13418bf80f4bSopenharmony_ci if (nextCmdRef.type == RenderCommandType::COPY_BUFFER_IMAGE) { 13428bf80f4bSopenharmony_ci const RenderCommandCopyBufferImage& nextRc = *static_cast<RenderCommandCopyBufferImage*>(nextCmdRef.rc); 13438bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextRc.copyType != RenderCommandCopyBufferImage::CopyType::UNDEFINED); 13448bf80f4bSopenharmony_ci srcHandle = nextRc.srcHandle; 13458bf80f4bSopenharmony_ci dstHandle = nextRc.dstHandle; 13468bf80f4bSopenharmony_ci srcImgLayers = nextRc.bufferImageCopy.imageSubresource; 13478bf80f4bSopenharmony_ci dstImgLayers = nextRc.bufferImageCopy.imageSubresource; 13488bf80f4bSopenharmony_ci } else if (nextCmdRef.type == RenderCommandType::COPY_IMAGE) { 13498bf80f4bSopenharmony_ci const RenderCommandCopyImage& nextRc = *static_cast<RenderCommandCopyImage*>(nextCmdRef.rc); 13508bf80f4bSopenharmony_ci srcHandle = nextRc.srcHandle; 13518bf80f4bSopenharmony_ci dstHandle = nextRc.dstHandle; 13528bf80f4bSopenharmony_ci srcImgLayers = nextRc.imageCopy.srcSubresource; 13538bf80f4bSopenharmony_ci dstImgLayers = nextRc.imageCopy.dstSubresource; 13548bf80f4bSopenharmony_ci } 13558bf80f4bSopenharmony_ci 13568bf80f4bSopenharmony_ci const bool needsSrcBarrier = 13578bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, srcHandle); 13588bf80f4bSopenharmony_ci if (needsSrcBarrier) { 13598bf80f4bSopenharmony_ci const RenderHandleType handleType = RenderHandleUtil::GetHandleType(srcHandle); 13608bf80f4bSopenharmony_ci PLUGIN_UNUSED(handleType); 13618bf80f4bSopenharmony_ci PLUGIN_ASSERT(handleType == RenderHandleType::GPU_IMAGE || handleType == RenderHandleType::GPU_BUFFER); 13628bf80f4bSopenharmony_ci if (handleType == RenderHandleType::GPU_BUFFER) { 13638bf80f4bSopenharmony_ci BindableBuffer bRes; 13648bf80f4bSopenharmony_ci bRes.handle = srcHandle; 13658bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheBuffer(params.renderNodeIndex, 13668bf80f4bSopenharmony_ci GpuResourceState { 13678bf80f4bSopenharmony_ci 0, CORE_ACCESS_TRANSFER_READ_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 13688bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 13698bf80f4bSopenharmony_ci } else { 13708bf80f4bSopenharmony_ci BindableImage bRes; 13718bf80f4bSopenharmony_ci bRes.handle = srcHandle; 13728bf80f4bSopenharmony_ci bRes.mip = srcImgLayers.mipLevel; 13738bf80f4bSopenharmony_ci bRes.layer = srcImgLayers.baseArrayLayer; 13748bf80f4bSopenharmony_ci bRes.imageLayout = CORE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 13758bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheImage(params.renderNodeIndex, 13768bf80f4bSopenharmony_ci GpuResourceState { 13778bf80f4bSopenharmony_ci 0, CORE_ACCESS_TRANSFER_READ_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 13788bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 13798bf80f4bSopenharmony_ci } 13808bf80f4bSopenharmony_ci } 13818bf80f4bSopenharmony_ci 13828bf80f4bSopenharmony_ci const bool needsDstBarrier = 13838bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, dstHandle); 13848bf80f4bSopenharmony_ci if (needsDstBarrier) { 13858bf80f4bSopenharmony_ci const RenderHandleType handleType = RenderHandleUtil::GetHandleType(dstHandle); 13868bf80f4bSopenharmony_ci PLUGIN_UNUSED(handleType); 13878bf80f4bSopenharmony_ci PLUGIN_ASSERT(handleType == RenderHandleType::GPU_IMAGE || handleType == RenderHandleType::GPU_BUFFER); 13888bf80f4bSopenharmony_ci if (handleType == RenderHandleType::GPU_BUFFER) { 13898bf80f4bSopenharmony_ci BindableBuffer bRes; 13908bf80f4bSopenharmony_ci bRes.handle = dstHandle; 13918bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheBuffer(params.renderNodeIndex, 13928bf80f4bSopenharmony_ci GpuResourceState { 13938bf80f4bSopenharmony_ci 0, CORE_ACCESS_TRANSFER_WRITE_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 13948bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 13958bf80f4bSopenharmony_ci } else { 13968bf80f4bSopenharmony_ci BindableImage bRes; 13978bf80f4bSopenharmony_ci bRes.handle = dstHandle; 13988bf80f4bSopenharmony_ci bRes.mip = dstImgLayers.mipLevel; 13998bf80f4bSopenharmony_ci bRes.layer = dstImgLayers.baseArrayLayer; 14008bf80f4bSopenharmony_ci bRes.imageLayout = CORE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 14018bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheImage(params.renderNodeIndex, 14028bf80f4bSopenharmony_ci GpuResourceState { 14038bf80f4bSopenharmony_ci 0, CORE_ACCESS_TRANSFER_WRITE_BIT, CORE_PIPELINE_STAGE_TRANSFER_BIT, params.gpuQueue }, 14048bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 14058bf80f4bSopenharmony_ci } 14068bf80f4bSopenharmony_ci } 14078bf80f4bSopenharmony_ci} 14088bf80f4bSopenharmony_ci 14098bf80f4bSopenharmony_civoid RenderGraph::HandleDispatchIndirect(ParameterCache& params, const uint32_t& commandListCommandIndex, 14108bf80f4bSopenharmony_ci const BASE_NS::array_view<const RenderCommandWithType>& cmdListRef) 14118bf80f4bSopenharmony_ci{ 14128bf80f4bSopenharmony_ci const uint32_t nextListIdx = commandListCommandIndex + 1; 14138bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextListIdx < cmdListRef.size()); 14148bf80f4bSopenharmony_ci const auto& nextCmdRef = cmdListRef[nextListIdx]; 14158bf80f4bSopenharmony_ci PLUGIN_ASSERT(nextCmdRef.type == RenderCommandType::DISPATCH_INDIRECT); 14168bf80f4bSopenharmony_ci 14178bf80f4bSopenharmony_ci const auto& nextRc = *static_cast<RenderCommandDispatchIndirect*>(nextCmdRef.rc); 14188bf80f4bSopenharmony_ci 14198bf80f4bSopenharmony_ci const bool needsArgsBarrier = 14208bf80f4bSopenharmony_ci CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, nextRc.argsHandle); 14218bf80f4bSopenharmony_ci if (needsArgsBarrier) { 14228bf80f4bSopenharmony_ci const BindableBuffer bRes = { nextRc.argsHandle, nextRc.offset, PipelineStateConstants::GPU_BUFFER_WHOLE_SIZE }; 14238bf80f4bSopenharmony_ci AddCommandBarrierAndUpdateStateCacheBuffer(params.renderNodeIndex, 14248bf80f4bSopenharmony_ci GpuResourceState { CORE_SHADER_STAGE_COMPUTE_BIT, CORE_ACCESS_INDIRECT_COMMAND_READ_BIT, 14258bf80f4bSopenharmony_ci CORE_PIPELINE_STAGE_DRAW_INDIRECT_BIT, params.gpuQueue }, 14268bf80f4bSopenharmony_ci bRes, params.rcWithType, params.combinedBarriers, currNodeGpuResourceTransfers_); 14278bf80f4bSopenharmony_ci } 14288bf80f4bSopenharmony_ci} 14298bf80f4bSopenharmony_ci 14308bf80f4bSopenharmony_civoid RenderGraph::HandleDescriptorSets(ParameterCache& params, 14318bf80f4bSopenharmony_ci const array_view<const RenderHandle>& descriptorSetHandlesForBarriers, 14328bf80f4bSopenharmony_ci const NodeContextDescriptorSetManager& nodeDescriptorSetMgrRef) 14338bf80f4bSopenharmony_ci{ 14348bf80f4bSopenharmony_ci for (const RenderHandle descriptorSetHandle : descriptorSetHandlesForBarriers) { 14358bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(descriptorSetHandle) == RenderHandleType::DESCRIPTOR_SET); 14368bf80f4bSopenharmony_ci 14378bf80f4bSopenharmony_ci const auto bindingResources = nodeDescriptorSetMgrRef.GetCpuDescriptorSetData(descriptorSetHandle); 14388bf80f4bSopenharmony_ci const auto& buffers = bindingResources.buffers; 14398bf80f4bSopenharmony_ci const auto& images = bindingResources.images; 14408bf80f4bSopenharmony_ci for (const auto& ref : buffers) { 14418bf80f4bSopenharmony_ci const uint32_t descriptorCount = ref.binding.descriptorCount; 14428bf80f4bSopenharmony_ci // skip, array bindings which are bound from first index, they have also descriptorCount 0 14438bf80f4bSopenharmony_ci if (descriptorCount == 0) { 14448bf80f4bSopenharmony_ci continue; 14458bf80f4bSopenharmony_ci } 14468bf80f4bSopenharmony_ci const uint32_t arrayOffset = ref.arrayOffset; 14478bf80f4bSopenharmony_ci PLUGIN_ASSERT((arrayOffset + descriptorCount - 1) <= buffers.size()); 14488bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < descriptorCount; ++idx) { 14498bf80f4bSopenharmony_ci // first is the ref, starting from 1 we use array offsets 14508bf80f4bSopenharmony_ci const auto& bRes = (idx == 0) ? ref : buffers[arrayOffset + idx - 1]; 14518bf80f4bSopenharmony_ci if (CheckForBarrierNeed(params.handledCustomBarriers, params.customBarrierCount, ref.resource.handle)) { 14528bf80f4bSopenharmony_ci UpdateStateAndCreateBarriersGpuBuffer(bRes.state, bRes.resource, params); 14538bf80f4bSopenharmony_ci } 14548bf80f4bSopenharmony_ci } 14558bf80f4bSopenharmony_ci } 14568bf80f4bSopenharmony_ci for (const auto& ref : images) { 14578bf80f4bSopenharmony_ci const uint32_t descriptorCount = ref.binding.descriptorCount; 14588bf80f4bSopenharmony_ci // skip, array bindings which are bound from first index, they have also descriptorCount 0 14598bf80f4bSopenharmony_ci if (descriptorCount == 0) { 14608bf80f4bSopenharmony_ci continue; 14618bf80f4bSopenharmony_ci } 14628bf80f4bSopenharmony_ci const uint32_t arrayOffset = ref.arrayOffset; 14638bf80f4bSopenharmony_ci PLUGIN_ASSERT((arrayOffset + descriptorCount - 1) <= images.size()); 14648bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < descriptorCount; ++idx) { 14658bf80f4bSopenharmony_ci // first is the ref, starting from 1 we use array offsets 14668bf80f4bSopenharmony_ci const auto& bRes = (idx == 0) ? ref : images[arrayOffset + idx - 1]; 14678bf80f4bSopenharmony_ci if (CheckForBarrierNeed( 14688bf80f4bSopenharmony_ci params.handledCustomBarriers, params.customBarrierCount, bRes.resource.handle)) { 14698bf80f4bSopenharmony_ci UpdateStateAndCreateBarriersGpuImage(bRes.state, bRes.resource, params); 14708bf80f4bSopenharmony_ci } 14718bf80f4bSopenharmony_ci } 14728bf80f4bSopenharmony_ci } 14738bf80f4bSopenharmony_ci } // end for 14748bf80f4bSopenharmony_ci} 14758bf80f4bSopenharmony_ci 14768bf80f4bSopenharmony_civoid RenderGraph::UpdateStateAndCreateBarriersGpuImage( 14778bf80f4bSopenharmony_ci const GpuResourceState& state, const BindableImage& res, RenderGraph::ParameterCache& params) 14788bf80f4bSopenharmony_ci{ 14798bf80f4bSopenharmony_ci const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(res.handle); 14808bf80f4bSopenharmony_ci if (arrayIndex >= static_cast<uint32_t>(gpuImageDataIndices_.size())) { 14818bf80f4bSopenharmony_ci return; 14828bf80f4bSopenharmony_ci } 14838bf80f4bSopenharmony_ci 14848bf80f4bSopenharmony_ci auto& ref = GetImageResourceStateRef(res.handle, state.gpuQueue); 14858bf80f4bSopenharmony_ci // NOTE: we previous patched the final render pass layouts here 14868bf80f4bSopenharmony_ci // ATM: we only path the swapchain image if needed 14878bf80f4bSopenharmony_ci 14888bf80f4bSopenharmony_ci const GpuResourceState& prevState = ref.state; 14898bf80f4bSopenharmony_ci const BindableImage& prevImage = ref.resource; 14908bf80f4bSopenharmony_ci const bool addMips = RenderHandleUtil::IsDynamicAdditionalStateResource(res.handle); 14918bf80f4bSopenharmony_ci const ResourceBarrier prevStateRb = addMips ? GetSrcImageBarrierMips(prevState, prevImage, res, ref.additionalState) 14928bf80f4bSopenharmony_ci : GetSrcImageBarrier(prevState, prevImage); 14938bf80f4bSopenharmony_ci 14948bf80f4bSopenharmony_ci const bool layoutChanged = (prevStateRb.optionalImageLayout != res.imageLayout); 14958bf80f4bSopenharmony_ci const bool accessFlagsChanged = (prevStateRb.accessFlags != state.accessFlags); 14968bf80f4bSopenharmony_ci const bool writeTarget = (prevStateRb.accessFlags & WRITE_ACCESS_FLAGS); 14978bf80f4bSopenharmony_ci const bool inputAttachment = (state.accessFlags == CORE_ACCESS_INPUT_ATTACHMENT_READ_BIT); 14988bf80f4bSopenharmony_ci // input attachments are handled with render passes and not with barriers 14998bf80f4bSopenharmony_ci if ((layoutChanged || accessFlagsChanged || writeTarget) && (!inputAttachment)) { 15008bf80f4bSopenharmony_ci if ((prevState.gpuQueue.type != GpuQueue::QueueType::UNDEFINED) && 15018bf80f4bSopenharmony_ci (prevState.gpuQueue.type != state.gpuQueue.type)) { 15028bf80f4bSopenharmony_ci PLUGIN_ASSERT(state.gpuQueue.type != GpuQueue::QueueType::UNDEFINED); 15038bf80f4bSopenharmony_ci 15048bf80f4bSopenharmony_ci PLUGIN_ASSERT(ref.prevRenderNodeIndex != params.renderNodeIndex); 15058bf80f4bSopenharmony_ci currNodeGpuResourceTransfers_.push_back(RenderGraph::GpuQueueTransferState { 15068bf80f4bSopenharmony_ci res.handle, ref.prevRenderNodeIndex, params.renderNodeIndex, prevImage.imageLayout, res.imageLayout }); 15078bf80f4bSopenharmony_ci } else { 15088bf80f4bSopenharmony_ci const ResourceBarrier dstImageBarrier = 15098bf80f4bSopenharmony_ci addMips ? GetDstImageBarrierMips(state, prevImage, res, ref.additionalState) 15108bf80f4bSopenharmony_ci : GetDstImageBarrier(state, res); 15118bf80f4bSopenharmony_ci params.combinedBarriers.push_back( 15128bf80f4bSopenharmony_ci CommandBarrier { res.handle, prevStateRb, prevState.gpuQueue, dstImageBarrier, params.gpuQueue }); 15138bf80f4bSopenharmony_ci } 15148bf80f4bSopenharmony_ci 15158bf80f4bSopenharmony_ci ref.state = state; 15168bf80f4bSopenharmony_ci ref.resource = res; 15178bf80f4bSopenharmony_ci ref.prevRc = params.rcWithType; 15188bf80f4bSopenharmony_ci ref.prevRenderNodeIndex = params.renderNodeIndex; 15198bf80f4bSopenharmony_ci if (addMips) { 15208bf80f4bSopenharmony_ci ModifyAdditionalImageState(res, ref.additionalState); 15218bf80f4bSopenharmony_ci } 15228bf80f4bSopenharmony_ci } 15238bf80f4bSopenharmony_ci} 15248bf80f4bSopenharmony_ci 15258bf80f4bSopenharmony_civoid RenderGraph::UpdateStateAndCreateBarriersGpuBuffer( 15268bf80f4bSopenharmony_ci const GpuResourceState& dstState, const BindableBuffer& res, RenderGraph::ParameterCache& params) 15278bf80f4bSopenharmony_ci{ 15288bf80f4bSopenharmony_ci const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(res.handle); 15298bf80f4bSopenharmony_ci if (arrayIndex >= static_cast<uint32_t>(gpuBufferDataIndices_.size())) { 15308bf80f4bSopenharmony_ci return; 15318bf80f4bSopenharmony_ci } 15328bf80f4bSopenharmony_ci 15338bf80f4bSopenharmony_ci // get the current state of the buffer 15348bf80f4bSopenharmony_ci auto& srcStateRef = GetBufferResourceStateRef(res.handle, dstState.gpuQueue); 15358bf80f4bSopenharmony_ci const ResourceBarrier prevStateRb = GetSrcBufferBarrier(srcStateRef.state, res); 15368bf80f4bSopenharmony_ci if ((prevStateRb.accessFlags != dstState.accessFlags) || (prevStateRb.accessFlags & WRITE_ACCESS_FLAGS)) { 15378bf80f4bSopenharmony_ci params.combinedBarriers.push_back(CommandBarrier { 15388bf80f4bSopenharmony_ci res.handle, prevStateRb, dstState.gpuQueue, GetDstBufferBarrier(dstState, res), params.gpuQueue }); 15398bf80f4bSopenharmony_ci } 15408bf80f4bSopenharmony_ci 15418bf80f4bSopenharmony_ci // update the cached state to match the situation after the barrier 15428bf80f4bSopenharmony_ci srcStateRef.state = dstState; 15438bf80f4bSopenharmony_ci srcStateRef.resource = res; 15448bf80f4bSopenharmony_ci srcStateRef.prevRc = params.rcWithType; 15458bf80f4bSopenharmony_ci srcStateRef.prevRenderNodeIndex = params.renderNodeIndex; 15468bf80f4bSopenharmony_ci} 15478bf80f4bSopenharmony_ci 15488bf80f4bSopenharmony_civoid RenderGraph::AddCommandBarrierAndUpdateStateCacheBuffer(const uint32_t renderNodeIndex, 15498bf80f4bSopenharmony_ci const GpuResourceState& newGpuResourceState, const BindableBuffer& newBuffer, 15508bf80f4bSopenharmony_ci const RenderCommandWithType& rcWithType, vector<CommandBarrier>& barriers, 15518bf80f4bSopenharmony_ci vector<RenderGraph::GpuQueueTransferState>& currNodeGpuResourceTransfer) 15528bf80f4bSopenharmony_ci{ 15538bf80f4bSopenharmony_ci auto& stateRef = GetBufferResourceStateRef(newBuffer.handle, newGpuResourceState.gpuQueue); 15548bf80f4bSopenharmony_ci const GpuResourceState srcState = stateRef.state; 15558bf80f4bSopenharmony_ci const BindableBuffer srcBuffer = stateRef.resource; 15568bf80f4bSopenharmony_ci 15578bf80f4bSopenharmony_ci if ((srcState.gpuQueue.type != GpuQueue::QueueType::UNDEFINED) && 15588bf80f4bSopenharmony_ci (srcState.gpuQueue.type != newGpuResourceState.gpuQueue.type)) { 15598bf80f4bSopenharmony_ci PLUGIN_ASSERT(newGpuResourceState.gpuQueue.type != GpuQueue::QueueType::UNDEFINED); 15608bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(newBuffer.handle) == RenderHandleType::GPU_IMAGE); 15618bf80f4bSopenharmony_ci PLUGIN_ASSERT(stateRef.prevRenderNodeIndex != renderNodeIndex); 15628bf80f4bSopenharmony_ci currNodeGpuResourceTransfer.push_back( 15638bf80f4bSopenharmony_ci RenderGraph::GpuQueueTransferState { newBuffer.handle, stateRef.prevRenderNodeIndex, renderNodeIndex, 15648bf80f4bSopenharmony_ci ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED, ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED }); 15658bf80f4bSopenharmony_ci } else { 15668bf80f4bSopenharmony_ci const ResourceBarrier srcBarrier = GetSrcBufferBarrier(srcState, srcBuffer); 15678bf80f4bSopenharmony_ci const ResourceBarrier dstBarrier = GetDstBufferBarrier(newGpuResourceState, newBuffer); 15688bf80f4bSopenharmony_ci 15698bf80f4bSopenharmony_ci barriers.push_back(CommandBarrier { 15708bf80f4bSopenharmony_ci newBuffer.handle, srcBarrier, srcState.gpuQueue, dstBarrier, newGpuResourceState.gpuQueue }); 15718bf80f4bSopenharmony_ci } 15728bf80f4bSopenharmony_ci 15738bf80f4bSopenharmony_ci stateRef.state = newGpuResourceState; 15748bf80f4bSopenharmony_ci stateRef.resource = newBuffer; 15758bf80f4bSopenharmony_ci stateRef.prevRc = rcWithType; 15768bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex = renderNodeIndex; 15778bf80f4bSopenharmony_ci} 15788bf80f4bSopenharmony_ci 15798bf80f4bSopenharmony_civoid RenderGraph::AddCommandBarrierAndUpdateStateCacheImage(const uint32_t renderNodeIndex, 15808bf80f4bSopenharmony_ci const GpuResourceState& newGpuResourceState, const BindableImage& newImage, const RenderCommandWithType& rcWithType, 15818bf80f4bSopenharmony_ci vector<CommandBarrier>& barriers, vector<RenderGraph::GpuQueueTransferState>& currNodeGpuResourceTransfer) 15828bf80f4bSopenharmony_ci{ 15838bf80f4bSopenharmony_ci // newGpuResourceState has queue transfer image layout in old optionalImageLayout 15848bf80f4bSopenharmony_ci 15858bf80f4bSopenharmony_ci auto& stateRef = GetImageResourceStateRef(newImage.handle, newGpuResourceState.gpuQueue); 15868bf80f4bSopenharmony_ci const GpuResourceState srcState = stateRef.state; 15878bf80f4bSopenharmony_ci const BindableImage srcImage = stateRef.resource; 15888bf80f4bSopenharmony_ci const bool addMips = RenderHandleUtil::IsDynamicAdditionalStateResource(newImage.handle); 15898bf80f4bSopenharmony_ci 15908bf80f4bSopenharmony_ci if ((srcState.gpuQueue.type != GpuQueue::QueueType::UNDEFINED) && 15918bf80f4bSopenharmony_ci (srcState.gpuQueue.type != newGpuResourceState.gpuQueue.type)) { 15928bf80f4bSopenharmony_ci PLUGIN_ASSERT(newGpuResourceState.gpuQueue.type != GpuQueue::QueueType::UNDEFINED); 15938bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(newImage.handle) == RenderHandleType::GPU_IMAGE); 15948bf80f4bSopenharmony_ci PLUGIN_ASSERT(stateRef.prevRenderNodeIndex != renderNodeIndex); 15958bf80f4bSopenharmony_ci currNodeGpuResourceTransfer.push_back(RenderGraph::GpuQueueTransferState { newImage.handle, 15968bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex, renderNodeIndex, srcImage.imageLayout, newImage.imageLayout }); 15978bf80f4bSopenharmony_ci } else { 15988bf80f4bSopenharmony_ci const ResourceBarrier srcBarrier = 15998bf80f4bSopenharmony_ci addMips ? GetSrcImageBarrierMips(srcState, srcImage, newImage, stateRef.additionalState) 16008bf80f4bSopenharmony_ci : GetSrcImageBarrier(srcState, srcImage); 16018bf80f4bSopenharmony_ci const ResourceBarrier dstBarrier = 16028bf80f4bSopenharmony_ci addMips ? GetDstImageBarrierMips(newGpuResourceState, srcImage, newImage, stateRef.additionalState) 16038bf80f4bSopenharmony_ci : GetDstImageBarrier(newGpuResourceState, newImage); 16048bf80f4bSopenharmony_ci 16058bf80f4bSopenharmony_ci barriers.push_back(CommandBarrier { 16068bf80f4bSopenharmony_ci newImage.handle, srcBarrier, srcState.gpuQueue, dstBarrier, newGpuResourceState.gpuQueue }); 16078bf80f4bSopenharmony_ci } 16088bf80f4bSopenharmony_ci 16098bf80f4bSopenharmony_ci stateRef.state = newGpuResourceState; 16108bf80f4bSopenharmony_ci stateRef.resource = newImage; 16118bf80f4bSopenharmony_ci stateRef.prevRc = rcWithType; 16128bf80f4bSopenharmony_ci stateRef.prevRenderNodeIndex = renderNodeIndex; 16138bf80f4bSopenharmony_ci if (addMips) { 16148bf80f4bSopenharmony_ci ModifyAdditionalImageState(newImage, stateRef.additionalState); 16158bf80f4bSopenharmony_ci } 16168bf80f4bSopenharmony_ci} 16178bf80f4bSopenharmony_ci 16188bf80f4bSopenharmony_ciRenderGraph::RenderGraphBufferState& RenderGraph::GetBufferResourceStateRef( 16198bf80f4bSopenharmony_ci const RenderHandle handle, const GpuQueue& queue) 16208bf80f4bSopenharmony_ci{ 16218bf80f4bSopenharmony_ci // NOTE: Do not call with non dynamic trackable 16228bf80f4bSopenharmony_ci const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle); 16238bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_BUFFER); 16248bf80f4bSopenharmony_ci if (arrayIndex < gpuBufferDataIndices_.size()) { 16258bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::IsDynamicResource(handle)); 16268bf80f4bSopenharmony_ci uint32_t dataIdx = gpuBufferDataIndices_[arrayIndex]; 16278bf80f4bSopenharmony_ci if (dataIdx == INVALID_TRACK_IDX) { 16288bf80f4bSopenharmony_ci if (!gpuBufferAvailableIndices_.empty()) { 16298bf80f4bSopenharmony_ci dataIdx = gpuBufferAvailableIndices_.back(); 16308bf80f4bSopenharmony_ci gpuBufferAvailableIndices_.pop_back(); 16318bf80f4bSopenharmony_ci } else { 16328bf80f4bSopenharmony_ci dataIdx = static_cast<uint32_t>(gpuBufferTracking_.size()); 16338bf80f4bSopenharmony_ci gpuBufferTracking_.emplace_back(); 16348bf80f4bSopenharmony_ci } 16358bf80f4bSopenharmony_ci gpuBufferDataIndices_[arrayIndex] = dataIdx; 16368bf80f4bSopenharmony_ci 16378bf80f4bSopenharmony_ci gpuBufferTracking_[dataIdx].resource.handle = handle; 16388bf80f4bSopenharmony_ci gpuBufferTracking_[dataIdx].state.gpuQueue = queue; // current queue for default state 16398bf80f4bSopenharmony_ci } 16408bf80f4bSopenharmony_ci return gpuBufferTracking_[dataIdx]; 16418bf80f4bSopenharmony_ci } 16428bf80f4bSopenharmony_ci 16438bf80f4bSopenharmony_ci return defaultBufferState_; 16448bf80f4bSopenharmony_ci} 16458bf80f4bSopenharmony_ci 16468bf80f4bSopenharmony_ciRenderGraph::RenderGraphImageState& RenderGraph::GetImageResourceStateRef( 16478bf80f4bSopenharmony_ci const RenderHandle handle, const GpuQueue& queue) 16488bf80f4bSopenharmony_ci{ 16498bf80f4bSopenharmony_ci // NOTE: Do not call with non dynamic trackable 16508bf80f4bSopenharmony_ci const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle); 16518bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_IMAGE); 16528bf80f4bSopenharmony_ci if (arrayIndex < gpuImageDataIndices_.size()) { 16538bf80f4bSopenharmony_ci // NOTE: render pass attachments expected to be dynamic resources always 16548bf80f4bSopenharmony_ci PLUGIN_ASSERT(RenderHandleUtil::IsDynamicResource(handle)); 16558bf80f4bSopenharmony_ci uint32_t dataIdx = gpuImageDataIndices_[arrayIndex]; 16568bf80f4bSopenharmony_ci if (dataIdx == INVALID_TRACK_IDX) { 16578bf80f4bSopenharmony_ci if (!gpuImageAvailableIndices_.empty()) { 16588bf80f4bSopenharmony_ci dataIdx = gpuImageAvailableIndices_.back(); 16598bf80f4bSopenharmony_ci gpuImageAvailableIndices_.pop_back(); 16608bf80f4bSopenharmony_ci } else { 16618bf80f4bSopenharmony_ci dataIdx = static_cast<uint32_t>(gpuImageTracking_.size()); 16628bf80f4bSopenharmony_ci gpuImageTracking_.emplace_back(); 16638bf80f4bSopenharmony_ci } 16648bf80f4bSopenharmony_ci gpuImageDataIndices_[arrayIndex] = dataIdx; 16658bf80f4bSopenharmony_ci 16668bf80f4bSopenharmony_ci gpuImageTracking_[dataIdx].resource.handle = handle; 16678bf80f4bSopenharmony_ci gpuImageTracking_[dataIdx].state.gpuQueue = queue; // current queue for default state 16688bf80f4bSopenharmony_ci if (RenderHandleUtil::IsDynamicAdditionalStateResource(handle) && 16698bf80f4bSopenharmony_ci (!gpuImageTracking_[dataIdx].additionalState.layouts)) { 16708bf80f4bSopenharmony_ci gpuImageTracking_[dataIdx].additionalState.layouts = make_unique<ImageLayout[]>(MAX_MIP_STATE_COUNT); 16718bf80f4bSopenharmony_ci } 16728bf80f4bSopenharmony_ci } 16738bf80f4bSopenharmony_ci return gpuImageTracking_[dataIdx]; 16748bf80f4bSopenharmony_ci } 16758bf80f4bSopenharmony_ci 16768bf80f4bSopenharmony_ci return defaultImageState_; 16778bf80f4bSopenharmony_ci} 16788bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 1679