From 20c50a041b42d0ec2bee5bda3dadb32b38d2bb6b Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 8 Jun 2023 15:24:05 +0800 Subject: [PATCH 01/57] add comment --- cocos/rendering/custom/pipeline.ts | 3 +++ native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 2dfa6d80c5a..5b55811c14c 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -330,6 +330,9 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { name: string, accessType: AccessType, slotName: string): void; + /** + * @beta function signature might change + */ addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; addRenderSubpass (subpassName: string): RenderSubpassBuilder; addMultisampleRenderSubpass ( diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 910922a0194..cde05b114d7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -455,6 +455,9 @@ class RenderPassBuilder : public BasicRenderPassBuilder { virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @beta function signature might change + */ virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; virtual RenderSubpassBuilder *addRenderSubpass(const ccstd::string &subpassName) = 0; virtual MultisampleRenderSubpassBuilder *addMultisampleRenderSubpass(uint32_t count, uint32_t quality, const ccstd::string &subpassName) = 0; From 38b7e2c781161f18a47c7db11d68305cde6ee50d Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 8 Jun 2023 16:33:29 +0800 Subject: [PATCH 02/57] fixing csm --- native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 2cca997478b..079ad2b725a 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -1189,9 +1189,9 @@ void setShadowUBOView( const auto &matShadowView = layer.getMatShadowView(); vec4ShadowInfo.set(matShadowView.m[0], matShadowView.m[4], matShadowView.m[8], layerThreshold); setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir0", vec4ShadowInfo, i); - vec4ShadowInfo.set(matShadowView.m[1], matShadowView.m[5], matShadowView.m[9], 0.0F); + vec4ShadowInfo.set(matShadowView.m[1], matShadowView.m[5], matShadowView.m[9], layer.getSplitCameraNear()); setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir1", vec4ShadowInfo, i); - vec4ShadowInfo.set(matShadowView.m[2], matShadowView.m[6], matShadowView.m[0], 0.0F); + vec4ShadowInfo.set(matShadowView.m[2], matShadowView.m[6], matShadowView.m[10], layer.getSplitCameraFar()); setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir2", vec4ShadowInfo, i); const auto &csmAtlas = layer.getCSMAtlas(); From 1b3dfa54ae656f6aba4a1a6771c15aac792d4ebe Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 8 Jun 2023 18:00:21 +0800 Subject: [PATCH 03/57] add shadow --- cocos/rendering/custom/define.ts | 2 +- cocos/rendering/post-process/passes/shadow-pass.ts | 3 --- cocos/rendering/post-process/post-process-builder.ts | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index 368b5bed4ad..f97e1a971e0 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -622,7 +622,7 @@ export function buildShadowPass (passName: Readonly, shadowPass.addDepthStencil(`${shadowMapName}Depth`, LoadOp.CLEAR, StoreOp.DISCARD, camera.clearDepth, camera.clearStencil, ClearFlagBit.DEPTH_STENCIL); } - const queue = shadowPass.addQueue(QueueHint.RENDER_OPAQUE); + const queue = shadowPass.addQueue(QueueHint.RENDER_OPAQUE, 'shadow-caster'); queue.addSceneOfCamera(camera, new LightInfo(light, level), SceneFlags.SHADOW_CASTER); queue.setViewport(new Viewport(area.x, area.y, area.width, area.height)); diff --git a/cocos/rendering/post-process/passes/shadow-pass.ts b/cocos/rendering/post-process/passes/shadow-pass.ts index 07a980a1d95..af623a6f019 100644 --- a/cocos/rendering/post-process/passes/shadow-pass.ts +++ b/cocos/rendering/post-process/passes/shadow-pass.ts @@ -11,9 +11,6 @@ export class ShadowPass extends BasePass { spotLightShadows: string[] = [] public render (camera: Camera, ppl: Pipeline): void { - // todo: disable shadow map pass with native engine - if (passContext.ppl) { if (passContext.ppl.type !== PipelineType.BASIC) return; } - passContext.shadowPass = this; const cameraID = getCameraUniqueID(camera); diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index 7f418429603..a6eb69d3963 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -158,7 +158,7 @@ export class PostProcessBuilder implements PipelineBuilder { if (!camera.scene) { continue; } - + ppl.update(camera); if (i === (cameras.length - 1)) { passContext.isFinalCamera = true; } From 0e7255bc9693147285c1bb61d3aa34d6ca1f0e9f Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 9 Jun 2023 15:05:00 +0800 Subject: [PATCH 04/57] adding sampler --- cocos/rendering/custom/web-pipeline.ts | 4 +++ .../pipeline/custom/NativeExecutor.cpp | 6 ++-- .../pipeline/custom/NativePipeline.cpp | 2 +- .../pipeline/custom/NativeRenderGraph.cpp | 36 +++++++++++++++---- .../renderer/pipeline/custom/NativeUtils.cpp | 2 +- .../pipeline/custom/RenderGraphTypes.h | 2 +- .../pipeline/custom/details/Utility.h | 8 ----- 7 files changed, 40 insertions(+), 20 deletions(-) diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 0be42879726..91040f8b007 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1062,6 +1062,10 @@ export class WebRenderPassBuilder extends WebSetter implements BasicRenderPassBu } addTexture (name: string, slotName: string, sampler: Sampler | null = null): void { this._addComputeResource(name, AccessType.READ, slotName); + if (sampler) { + const descriptorID = this._layoutGraph.attributeIndex.get(slotName)!; + this._data.samplers.set(descriptorID, sampler); + } } addStorageBuffer (name: string, accessType: AccessType, slotName: string): void { this._addComputeResource(name, accessType, slotName); diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index c4c46fc95f6..ced9a4cfde9 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -401,7 +401,7 @@ void updateGlobal( } auto* sampler = descriptorSet.getSampler(bindId); if (!sampler || isUpdate) { - bindGlobalDesc(descriptorSet, bindId, value.get()); + bindGlobalDesc(descriptorSet, bindId, value); } } } @@ -586,7 +586,7 @@ gfx::DescriptorSet* initDescriptorSet( CC_EXPECTS(d.count == 1); auto iter = user.samplers.find(d.descriptorID.value); if (iter != user.samplers.end()) { - newSet->bindSampler(bindID, iter->second.get()); + newSet->bindSampler(bindID, iter->second); } else { gfx::SamplerInfo info{}; auto* sampler = device->getSampler(info); @@ -741,7 +741,7 @@ gfx::DescriptorSet* updatePerPassDescriptorSet( CC_EXPECTS(d.count == 1); auto iter = user.samplers.find(d.descriptorID.value); if (iter != user.samplers.end()) { - newSet->bindSampler(bindID, iter->second.get()); + newSet->bindSampler(bindID, iter->second); } else { auto* prevSampler = prevSet.getSampler(bindID); CC_ENSURES(prevSampler); diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 3cfe31f03ba..a1dd0e5d812 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -511,7 +511,7 @@ void NativePipeline::updateShadingRateTexture( void NativePipeline::beginFrame() { } -void NativePipeline::update(const scene::Camera* camera) { +void NativePipeline::update(const scene::Camera *camera) { const auto *sceneData = getPipelineSceneData(); sceneData->getCSMLayers()->update(sceneData, camera); } diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 079ad2b725a..93ea8d8e72d 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -470,7 +470,6 @@ void NativeRenderPassBuilder::addDepthStencil( void NativeRenderPassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - std::ignore = sampler; addComputeView( name, ComputeView{ @@ -482,6 +481,13 @@ void NativeRenderPassBuilder::addTexture( ClearValue{}, gfx::ShaderStageFlagBit::NONE, renderGraph->get_allocator()}); + if (sampler) { + auto iter = layoutGraph->attributeIndex.find(std::string_view{slotName}); + if (iter != layoutGraph->attributeIndex.end()) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + data.samplers[iter->second.value] = sampler; + } + } } void NativeRenderPassBuilder::addStorageBuffer( @@ -739,7 +745,6 @@ void NativeRenderSubpassBuilderImpl::addDepthStencil( void NativeRenderSubpassBuilderImpl::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - std::ignore = sampler; addComputeView( name, ComputeView{ @@ -751,6 +756,13 @@ void NativeRenderSubpassBuilderImpl::addTexture( ClearValue{}, gfx::ShaderStageFlagBit::NONE, renderGraph->get_allocator()}); + if (sampler) { + auto iter = layoutGraph->attributeIndex.find(std::string_view{slotName}); + if (iter != layoutGraph->attributeIndex.end()) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + data.samplers[iter->second.value] = sampler; + } + } } void NativeRenderSubpassBuilderImpl::addStorageBuffer( @@ -924,7 +936,6 @@ void NativeComputeSubpassBuilder::addRenderTarget(const ccstd::string &name, con void NativeComputeSubpassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - std::ignore = sampler; addComputeView( name, ComputeView{ @@ -936,6 +947,13 @@ void NativeComputeSubpassBuilder::addTexture( ClearValue{}, gfx::ShaderStageFlagBit::NONE, renderGraph->get_allocator()}); + if (sampler) { + auto iter = layoutGraph->attributeIndex.find(std::string_view{slotName}); + if (iter != layoutGraph->attributeIndex.end()) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + data.samplers[iter->second.value] = sampler; + } + } } void NativeComputeSubpassBuilder::addStorageBuffer( @@ -1290,9 +1308,9 @@ void setTextureUBOView( gfx::Address::CLAMP}; auto *pointSampler = device.getSampler(samplerPointInfo); setSamplerImpl(data, layoutGraph, "cc_shadowMap", pointSampler); - //setTextureImpl(data, layoutGraph, "cc_shadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); + // setTextureImpl(data, layoutGraph, "cc_shadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); setSamplerImpl(data, layoutGraph, "cc_spotShadowMap", pointSampler); - //setTextureImpl(data, layoutGraph, "cc_spotShadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); + // setTextureImpl(data, layoutGraph, "cc_spotShadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); } } // namespace @@ -1642,7 +1660,6 @@ void NativeComputeQueueBuilder::addDispatch( void NativeComputePassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - std::ignore = sampler; addComputeView( name, ComputeView{ @@ -1654,6 +1671,13 @@ void NativeComputePassBuilder::addTexture( ClearValue{}, gfx::ShaderStageFlagBit::NONE, renderGraph->get_allocator()}); + if (sampler) { + auto iter = layoutGraph->attributeIndex.find(std::string_view{slotName}); + if (iter != layoutGraph->attributeIndex.end()) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + data.samplers[iter->second.value] = sampler; + } + } } void NativeComputePassBuilder::addStorageBuffer( diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp index 38de2595ffb..75af2336a16 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp @@ -222,7 +222,7 @@ void setReadWriteTextureImpl(RenderData &data, const LayoutGraphData &lg, const void setSamplerImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Sampler *sampler) { auto nameID = getNameID(lg.attributeIndex, name); - data.samplers[nameID.value].ptr = sampler; + data.samplers[nameID.value] = sampler; } LayoutGraphData::vertex_descriptor getSubpassOrPassID( diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index 81cd30ec922..cb5c0baeb23 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -802,7 +802,7 @@ struct RenderData { PmrUnorderedMap> constants; PmrUnorderedMap> buffers; PmrUnorderedMap> textures; - PmrUnorderedMap> samplers; + PmrUnorderedMap samplers; ccstd::pmr::string custom; }; diff --git a/native/cocos/renderer/pipeline/custom/details/Utility.h b/native/cocos/renderer/pipeline/custom/details/Utility.h index 8cdba869d62..938178db9a1 100644 --- a/native/cocos/renderer/pipeline/custom/details/Utility.h +++ b/native/cocos/renderer/pipeline/custom/details/Utility.h @@ -58,12 +58,4 @@ struct TransparentStringEqual { } }; -template -struct ObserverPtr { - T* get() const noexcept { - return ptr; - } - T* ptr; -}; - } // namespace cc From 4c036faceabed7ead4aa8dc60cd43b1f6611547c Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 9 Jun 2023 15:11:41 +0800 Subject: [PATCH 05/57] samplers added --- .../pipeline/custom/NativeExecutor.cpp | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index ced9a4cfde9..91276b4217b 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -526,9 +526,9 @@ gfx::DescriptorSet* initDescriptorSet( CC_EXPECTS(d.count == 1); CC_EXPECTS(d.type >= gfx::Type::SAMPLER1D && d.type <= gfx::Type::SAMPLER_CUBE); - - auto iter = resourceIndex.find(d.descriptorID); - if (iter != resourceIndex.end()) { + // texture + if (auto iter = resourceIndex.find(d.descriptorID); + iter != resourceIndex.end()) { // render graph textures auto* texture = resg.getTexture(iter->second); CC_ENSURES(texture); @@ -576,7 +576,15 @@ gfx::DescriptorSet* initDescriptorSet( } newSet->bindTexture(bindID, defaultResource.getTexture(type)); } + } // texture end + + // user provided samplers + if (auto iter = user.samplers.find(d.descriptorID.value); + iter != user.samplers.end()) { + newSet->bindSampler(bindID, iter->second); } + + // increase descriptor binding offset bindID += d.count; } break; @@ -724,14 +732,23 @@ gfx::DescriptorSet* updatePerPassDescriptorSet( CC_EXPECTS(d.count == 1); CC_EXPECTS(d.type >= gfx::Type::SAMPLER1D && d.type <= gfx::Type::SAMPLER_CUBE); - auto iter = user.textures.find(d.descriptorID.value); - if (iter != user.textures.end()) { + // textures + if (auto iter = user.textures.find(d.descriptorID.value); + iter != user.textures.end()) { newSet->bindTexture(bindID, iter->second.get()); } else { auto* prevTexture = prevSet.getTexture(bindID); CC_ENSURES(prevTexture); newSet->bindTexture(bindID, prevTexture); } + + // samplers + if (auto iter = user.samplers.find(d.descriptorID.value); + iter != user.samplers.end()) { + newSet->bindSampler(bindID, iter->second); + } + + // increase descriptor binding offset bindID += d.count; } break; From ac03ee383966510e46e4d738e92e2be91895b4b1 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 9 Jun 2023 15:35:13 +0800 Subject: [PATCH 06/57] fix csm crash --- native/cocos/renderer/pipeline/custom/NativePipeline.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index a1dd0e5d812..c8f13b5dfc9 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -513,7 +513,11 @@ void NativePipeline::beginFrame() { void NativePipeline::update(const scene::Camera *camera) { const auto *sceneData = getPipelineSceneData(); - sceneData->getCSMLayers()->update(sceneData, camera); + const auto *shadows = sceneData->getShadows(); + if (shadows && shadows->isEnabled() && shadows->getType() == scene::ShadowType::SHADOW_MAP && + camera && camera->getScene() && camera->getScene()->getMainLight()) { + sceneData->getCSMLayers()->update(sceneData, camera); + } } void NativePipeline::endFrame() { From 76399f5e1968446b60571926d9997f0529d30d28 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Mon, 12 Jun 2023 19:27:50 +0800 Subject: [PATCH 07/57] remove addRasterView, addComputeView --- cocos/rendering/custom/compiler.ts | 4 +- cocos/rendering/custom/define.ts | 293 +++--------------- cocos/rendering/custom/executor.ts | 5 +- cocos/rendering/custom/pipeline.ts | 22 +- cocos/rendering/custom/render-graph.ts | 74 ++++- cocos/rendering/custom/types.ts | 134 +------- cocos/rendering/custom/web-pipeline.ts | 37 +-- .../post-process/utils/pass-context.ts | 6 +- .../pipeline/custom/NativePipelineTypes.h | 11 - .../pipeline/custom/NativeRenderGraph.cpp | 202 ++++++------ .../pipeline/custom/RenderCommonFwd.h | 25 -- .../pipeline/custom/RenderCommonJsb.cpp | 201 ------------ .../pipeline/custom/RenderCommonJsb.h | 15 - .../pipeline/custom/RenderCommonNames.h | 3 - .../custom/RenderCommonSerialization.h | 60 ---- .../pipeline/custom/RenderCommonTypes.cpp | 88 ------ .../pipeline/custom/RenderCommonTypes.h | 141 --------- .../renderer/pipeline/custom/RenderGraphFwd.h | 18 ++ .../pipeline/custom/RenderGraphTypes.cpp | 88 ++++++ .../pipeline/custom/RenderGraphTypes.h | 136 ++++++++ .../pipeline/custom/RenderInterfaceTypes.h | 20 -- 21 files changed, 468 insertions(+), 1115 deletions(-) diff --git a/cocos/rendering/custom/compiler.ts b/cocos/rendering/custom/compiler.ts index d2ba1512fdf..bf20c0a2184 100644 --- a/cocos/rendering/custom/compiler.ts +++ b/cocos/rendering/custom/compiler.ts @@ -29,9 +29,9 @@ import { DefaultVisitor, depthFirstSearch, ReferenceGraphView } from './graph'; import { LayoutGraphData } from './layout-graph'; import { BasicPipeline } from './pipeline'; import { Blit, ClearView, ComputePass, ComputeSubpass, CopyPass, Dispatch, FormatView, ManagedBuffer, ManagedResource, ManagedTexture, MovePass, - RasterPass, RasterSubpass, RaytracePass, RenderGraph, RenderGraphVisitor, + RasterPass, RasterSubpass, RaytracePass, RenderGraph, RenderGraphVisitor, RasterView, ComputeView, RenderQueue, RenderSwapchain, ResolvePass, ResourceGraph, ResourceGraphVisitor, SceneData, SubresourceView } from './render-graph'; -import { AccessType, RasterView, ComputeView, ResourceResidency, SceneFlags } from './types'; +import { AccessType, ResourceResidency, SceneFlags } from './types'; let hashCode = 0; diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index 28e4eca2bca..00bffd8c107 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -32,8 +32,8 @@ import { import { supportsR32FloatTexture, supportsRGBA16HalfFloatTexture } from '../define'; import { BasicPipeline, Pipeline } from './pipeline'; import { - AccessType, AttachmentType, ComputeView, CopyPair, LightInfo, - QueueHint, RasterView, ResourceResidency, SceneFlags, UpdateFrequency, UploadPair, + AccessType, AttachmentType, CopyPair, LightInfo, + QueueHint, ResourceResidency, SceneFlags, UpdateFrequency, UploadPair, } from './types'; import { Vec2, Vec3, Vec4, macro, geometry, toRadian, cclegacy, assert, nextPow2 } from '../../core'; import { ImageAsset, Material, Texture2D } from '../../asset/assets'; @@ -43,7 +43,6 @@ import { RenderData } from './render-graph'; import { WebPipeline } from './web-pipeline'; import { DescriptorSetData } from './layout-graph'; import { AABB } from '../../core/geometry'; -import { MeshRenderer } from '../../3d'; import { DebugViewCompositeType, DebugViewSingleType } from '../debug-view'; const _rangedDirLightBoundingBox = new AABB(0.0, 0.0, 0.0, 0.5, 0.5, 0.5); @@ -937,141 +936,6 @@ export function buildUIPass (camera: Camera, } } -export function buildNativeForwardPass (camera: Camera, ppl: BasicPipeline) { - const cameraID = getCameraUniqueID(camera); - const cameraName = `Camera${cameraID}`; - const area = getRenderArea(camera, camera.window.width, camera.window.height); - const width = area.width; - const height = area.height; - - // Resources - const forwardPassRTName = `dsForwardPassColor${cameraName}`; - const forwardPassDSName = `dsForwardPassDS${cameraName}`; - if (!ppl.containsResource(forwardPassRTName)) { - ppl.addRenderTexture(forwardPassRTName, Format.BGRA8, width, height, camera.window); - ppl.addDepthStencil(forwardPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); - } - - ppl.updateRenderWindow(forwardPassRTName, camera.window); - ppl.updateDepthStencil(forwardPassDSName, width, height); - // Passes - const forwardPass = ppl.addRenderPass(width, height, 'default'); - forwardPass.name = `CameraForwardPass${cameraID}`; - forwardPass.setViewport(new Viewport(area.x, area.y, width, height)); - - const cameraRenderTargetLoadOp = getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.RENDER_TARGET); - const cameraDepthStencilLoadOp = getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.DEPTH_STENCIL); - - forwardPass.addRasterView(forwardPassRTName, - new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, - cameraRenderTargetLoadOp, - StoreOp.STORE, - getClearFlags(AttachmentType.RENDER_TARGET, camera.clearFlag, cameraRenderTargetLoadOp), - new Color(camera.clearColor.x, camera.clearColor.y, camera.clearColor.z, camera.clearColor.w))); - forwardPass.addRasterView(forwardPassDSName, - new RasterView('_', - AccessType.WRITE, AttachmentType.DEPTH_STENCIL, - cameraDepthStencilLoadOp, - StoreOp.STORE, - getClearFlags(AttachmentType.DEPTH_STENCIL, camera.clearFlag, cameraDepthStencilLoadOp), - new Color(camera.clearDepth, camera.clearStencil, 0, 0))); - - forwardPass - .addQueue(QueueHint.RENDER_OPAQUE) - .addSceneOfCamera(camera, new LightInfo(), - SceneFlags.OPAQUE_OBJECT - | SceneFlags.PLANAR_SHADOW - | SceneFlags.CUTOUT_OBJECT - | SceneFlags.DEFAULT_LIGHTING - | SceneFlags.DRAW_INSTANCING); - forwardPass - .addQueue(QueueHint.RENDER_TRANSPARENT) - .addSceneOfCamera(camera, new LightInfo(), - SceneFlags.TRANSPARENT_OBJECT - | SceneFlags.GEOMETRY); - forwardPass - .addQueue(QueueHint.RENDER_TRANSPARENT) - .addSceneOfCamera(camera, new LightInfo(), - SceneFlags.UI); - forwardPass.showStatistics = true; -} - -export function buildNativeDeferredPipeline (camera: Camera, ppl: BasicPipeline) { - const cameraID = getCameraUniqueID(camera); - const area = getRenderArea(camera, camera.window.width, camera.window.height); - const width = area.width; - const height = area.height; - if (!ppl.containsResource('Albedo')) { - // GBuffers - ppl.addRenderTarget('Albedo', Format.RGBA16F, width, height, ResourceResidency.MANAGED); - ppl.addRenderTarget('Normal', Format.RGBA16F, width, height, ResourceResidency.MANAGED); - ppl.addRenderTarget('Emissive', Format.RGBA16F, width, height, ResourceResidency.MANAGED); - ppl.addDepthStencil('DepthStencil', Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); - // Lighting - ppl.addRenderTexture('Color', Format.BGRA8, width, height, camera.window); - } - if (!lightingInfo) { - lightingInfo = new LightingInfo(); - } - // GeometryPass - { - const gBufferPass = ppl.addRenderPass(width, height, 'default'); - gBufferPass.name = 'GeometryPass'; - gBufferPass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); - - gBufferPass.addRasterView('Albedo', new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); - gBufferPass.addRasterView('Normal', new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); - gBufferPass.addRasterView('Emissive', new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, StoreOp.STORE, ClearFlagBit.COLOR)); - gBufferPass.addRasterView('DepthStencil', new RasterView('_', - AccessType.WRITE, AttachmentType.DEPTH_STENCIL, - LoadOp.CLEAR, StoreOp.STORE, - ClearFlagBit.DEPTH_STENCIL, - new Color(1, 0, 0, 0))); - gBufferPass - .addQueue(QueueHint.RENDER_OPAQUE) - .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.CUTOUT_OBJECT); - } - // LightingPass - { - const lightingPass = ppl.addRenderPass(width, height, 'default'); - lightingPass.name = 'LightingPass'; - lightingPass.setViewport(new Viewport(area.x, area.y, width, height)); - - const lightingClearColor = new Color(0, 0, 0, 0); - if (camera.clearFlag & ClearFlagBit.COLOR) { - lightingClearColor.x = camera.clearColor.x; - lightingClearColor.y = camera.clearColor.y; - lightingClearColor.z = camera.clearColor.z; - } - lightingClearColor.w = 1; - lightingPass.addRasterView('Color', new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, StoreOp.STORE, - camera.clearFlag, - lightingClearColor)); - - lightingPass.addComputeView('Albedo', new ComputeView('gbuffer_albedoMap')); - lightingPass.addComputeView('Normal', new ComputeView('gbuffer_normalMap')); - lightingPass.addComputeView('Emissive', new ComputeView('gbuffer_emissiveMap')); - lightingPass.addComputeView('DepthStencil', new ComputeView('depth_stencil')); - - lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addCameraQuad( - camera, lightingInfo.deferredLightingMaterial, 0, - SceneFlags.VOLUMETRIC_LIGHTING, - ); - lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, - new LightInfo(), - SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); - } -} - export function updateCameraUBO (setter: any, camera: Readonly, ppl: Readonly) { const pipeline = cclegacy.director.root.pipeline; const sceneData = ppl.pipelineSceneData; @@ -1485,18 +1349,10 @@ function _buildSSSSBlurPass (camera: Camera, sampler.minFilter = Filter.POINT; sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; - const computeView = new ComputeView(); - computeView.name = 'depthRaw'; - copyInputDSPass.addComputeView(inputDS, computeView); - } - const copyInputDSPassView = new RasterView('_', - AccessType.WRITE, - AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, - StoreOp.STORE, - camera.clearFlag, - new Color(1.0, 0.0, 0.0, 0.0)); - copyInputDSPass.addRasterView(ssssBlurDSName, copyInputDSPassView); + copyInputDSPass.addTexture(inputDS, 'depthRaw'); + } + copyInputDSPass.addRenderTarget(ssssBlurDSName, + LoadOp.CLEAR, StoreOp.STORE, new Color(1.0, 0.0, 0.0, 0.0)); copyInputDSPass.addQueue(QueueHint.RENDER_OPAQUE | QueueHint.RENDER_TRANSPARENT).addCameraQuad( camera, ssssBlurData.ssssBlurMaterial, COPY_INPUT_DS_PASS_INDEX, SceneFlags.NONE, @@ -1512,9 +1368,7 @@ function _buildSSSSBlurPass (camera: Camera, sampler.minFilter = Filter.POINT; sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; - const computeView = new ComputeView(); - computeView.name = 'colorTex'; - ssssblurXPass.addComputeView(inputRT, computeView); + ssssblurXPass.addTexture(inputRT, 'colorTex'); } if (ppl.containsResource(ssssBlurDSName)) { const verId = webPipeline.resourceGraph.vertex(ssssBlurDSName); @@ -1522,26 +1376,11 @@ function _buildSSSSBlurPass (camera: Camera, sampler.minFilter = Filter.POINT; sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; - const computeView = new ComputeView(); - computeView.name = 'depthTex'; - ssssblurXPass.addComputeView(ssssBlurDSName, computeView); - } - const ssssBlurXPassRTView = new RasterView('_', - AccessType.WRITE, - AttachmentType.RENDER_TARGET, - LoadOp.CLEAR, - StoreOp.STORE, - camera.clearFlag, - ssssBlurClearColor); - ssssblurXPass.addRasterView(ssssBlurRTName, ssssBlurXPassRTView); - const ssssBlurXPassDSView = new RasterView('_', - AccessType.WRITE, - AttachmentType.DEPTH_STENCIL, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, - new Color(camera.clearDepth, camera.clearStencil, 0.0, 0.0)); - ssssblurXPass.addRasterView(inputDS, ssssBlurXPassDSView); + ssssblurXPass.addTexture(ssssBlurDSName, 'depthTex'); + } + ssssblurXPass.addRenderTarget(ssssBlurRTName, LoadOp.CLEAR, StoreOp.STORE, ssssBlurClearColor); + ssssblurXPass.addDepthStencil(inputDS, LoadOp.LOAD, StoreOp.STORE, + camera.clearDepth, camera.clearStencil, camera.clearFlag); ssssBlurData.ssssBlurMaterial.setProperty('blurInfo', new Vec4(ssssBlurData.ssssFov, ssssBlurData.ssssWidth, ssssBlurData.boundingBox, ssssBlurData.ssssScale), SSSS_BLUR_X_PASS_INDEX); ssssBlurData.ssssBlurMaterial.setProperty('kernel', ssssBlurData.kernel, SSSS_BLUR_X_PASS_INDEX); @@ -1560,9 +1399,7 @@ function _buildSSSSBlurPass (camera: Camera, sampler.minFilter = Filter.POINT; sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; - const computeView = new ComputeView(); - computeView.name = 'colorTex'; - ssssblurYPass.addComputeView(ssssBlurRTName, computeView); + ssssblurYPass.addTexture(ssssBlurRTName, 'colorTex'); } if (ppl.containsResource(ssssBlurDSName)) { const verId = webPipeline.resourceGraph.vertex(ssssBlurDSName); @@ -1570,26 +1407,11 @@ function _buildSSSSBlurPass (camera: Camera, sampler.minFilter = Filter.POINT; sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; - const computeView = new ComputeView(); - computeView.name = 'depthTex'; - ssssblurYPass.addComputeView(ssssBlurDSName, computeView); + ssssblurYPass.addTexture(ssssBlurDSName, 'depthTex'); } - const ssssBlurYPassView = new RasterView('_', - AccessType.WRITE, - AttachmentType.RENDER_TARGET, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, - ssssBlurClearColor); - ssssblurYPass.addRasterView(inputRT, ssssBlurYPassView); - const ssssBlurYPassDSView = new RasterView('_', - AccessType.WRITE, - AttachmentType.DEPTH_STENCIL, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, - new Color(camera.clearDepth, camera.clearStencil, 0.0, 0.0)); - ssssblurYPass.addRasterView(inputDS, ssssBlurYPassDSView); + ssssblurYPass.addRenderTarget(inputRT, LoadOp.LOAD, StoreOp.STORE, ssssBlurClearColor); + ssssblurYPass.addDepthStencil(inputDS, LoadOp.LOAD, StoreOp.STORE, + camera.clearDepth, camera.clearStencil, camera.clearFlag); ssssBlurData.ssssBlurMaterial.setProperty('blurInfo', new Vec4(ssssBlurData.ssssFov, ssssBlurData.ssssWidth, ssssBlurData.boundingBox, ssssBlurData.ssssScale), SSSS_BLUR_Y_PASS_INDEX); ssssBlurData.ssssBlurMaterial.setProperty('kernel', ssssBlurData.kernel, SSSS_BLUR_Y_PASS_INDEX); @@ -1651,24 +1473,15 @@ export function buildToneMappingPass (camera: Camera, toneMappingPass.name = `CameraToneMappingPass${cameraID}`; toneMappingPass.setViewport(new Viewport(area.x, area.y, area.width, area.height)); if (ppl.containsResource(inputRT)) { - const computeView = new ComputeView(); - computeView.name = 'u_texSampler'; - toneMappingPass.addComputeView(inputRT, computeView); + toneMappingPass.addTexture(inputRT, 'u_texSampler'); } - const toneMappingPassView = new RasterView('_', - AccessType.WRITE, AttachmentType.RENDER_TARGET, + toneMappingPass.addRenderTarget(toneMappingPassRTName, getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.RENDER_TARGET), - StoreOp.STORE, - camera.clearFlag, - toneMappingClearColor); - const toneMappingPassDSView = new RasterView('_', - AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + StoreOp.STORE, toneMappingClearColor); + toneMappingPass.addDepthStencil(toneMappingPassDS, getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.DEPTH_STENCIL), StoreOp.STORE, - camera.clearFlag, - new Color(camera.clearDepth, camera.clearStencil, 0, 0)); - toneMappingPass.addRasterView(toneMappingPassRTName, toneMappingPassView); - toneMappingPass.addRasterView(toneMappingPassDS, toneMappingPassDSView); + camera.clearDepth, camera.clearStencil, camera.clearFlag); toneMappingPass.addQueue(QueueHint.NONE).addFullscreenQuad( toneMappingInfo.toneMappingMaterial, 0, SceneFlags.NONE, ); @@ -1707,22 +1520,12 @@ export function buildTransparencyPass (camera: Camera, alphaPass.addTexture(spotShadowName, 'cc_spotShadowMap'); } } - const alphaPassView = new RasterView('_', - AccessType.WRITE, - AttachmentType.RENDER_TARGET, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, + alphaPass.addRenderTarget(inputRT, + LoadOp.LOAD, StoreOp.STORE, new Color(camera.clearDepth, camera.clearStencil, 0, 0)); - const alphaPassDSView = new RasterView('_', - AccessType.WRITE, - AttachmentType.DEPTH_STENCIL, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, - new Color(camera.clearDepth, camera.clearStencil, 0, 0)); - alphaPass.addRasterView(inputRT, alphaPassView); - alphaPass.addRasterView(inputDS, alphaPassDSView); + alphaPass.addDepthStencil(inputDS, + LoadOp.LOAD, StoreOp.STORE, + camera.clearDepth, camera.clearStencil, camera.clearFlag); alphaPass .addQueue(QueueHint.RENDER_TRANSPARENT) .addSceneOfCamera(camera, new LightInfo(), SceneFlags.TRANSPARENT_OBJECT | SceneFlags.GEOMETRY); @@ -1748,32 +1551,20 @@ function _buildSpecularPass (camera: Camera, specalurPass.setViewport(new Viewport(area.x, area.y, width, height)); for (const dirShadowName of cameraInfo.mainLightShadowNames) { if (ppl.containsResource(dirShadowName)) { - const computeView = new ComputeView('cc_shadowMap'); - specalurPass.addComputeView(dirShadowName, computeView); + specalurPass.addTexture(dirShadowName, 'cc_shadowMap'); } } for (const spotShadowName of cameraInfo.spotLightShadowNames) { if (ppl.containsResource(spotShadowName)) { - const computeView = new ComputeView('cc_spotShadowMap'); - specalurPass.addComputeView(spotShadowName, computeView); + specalurPass.addTexture(spotShadowName, 'cc_spotShadowMap'); } } - const passView = new RasterView('_', - AccessType.WRITE, - AttachmentType.RENDER_TARGET, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, + specalurPass.addRenderTarget(inputRT, + LoadOp.LOAD, StoreOp.STORE, new Color(camera.clearColor.x, camera.clearColor.y, camera.clearColor.z, camera.clearColor.w)); - const passDSView = new RasterView('_', - AccessType.WRITE, - AttachmentType.DEPTH_STENCIL, - LoadOp.LOAD, - StoreOp.STORE, - camera.clearFlag, - new Color(camera.clearDepth, camera.clearStencil, 0, 0)); - specalurPass.addRasterView(inputRT, passView); - specalurPass.addRasterView(inputDS, passDSView); + specalurPass.addDepthStencil(inputDS, + LoadOp.LOAD, StoreOp.STORE, + camera.clearDepth, camera.clearStencil, camera.clearFlag); specalurPass .addQueue(QueueHint.RENDER_OPAQUE, 'default') .addSceneOfCamera(camera, new LightInfo(), @@ -1977,9 +1768,7 @@ function _buildHBAOPass (camera: Camera, sampler.minFilter = sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; sampler.addressU = sampler.addressV = Address.CLAMP; - const computeView = new ComputeView(); - computeView.name = 'DepthTex'; - hbaoPass.addComputeView(inputDS, computeView); + hbaoPass.addTexture(inputDS, 'DepthTex'); } hbaoPass.addRenderTarget( hbaoRTName, @@ -2040,9 +1829,7 @@ function _buildHBAOBlurPass (camera: Camera, sampler.minFilter = sampler.magFilter = Filter.POINT; sampler.mipFilter = Filter.NONE; sampler.addressU = sampler.addressV = Address.CLAMP; - const computeView = new ComputeView(); - computeView.name = 'DepthTex'; - blurPass.addComputeView(inputDS, computeView); + blurPass.addTexture(inputDS, 'DepthTex'); } if (ppl.containsResource(inputRTName)) { const webPipeline = (ppl as WebPipeline); @@ -2051,9 +1838,7 @@ function _buildHBAOBlurPass (camera: Camera, sampler.minFilter = sampler.magFilter = Filter.LINEAR; sampler.mipFilter = Filter.NONE; sampler.addressU = sampler.addressV = Address.CLAMP; - const computeView = new ComputeView(); - computeView.name = 'AOTexNearest'; - blurPass.addComputeView(inputRTName, computeView); + blurPass.addTexture(inputRTName, 'AOTexNearest'); } blurPass.addRenderTarget( outputRTName, @@ -2104,9 +1889,7 @@ function _buildHBAOCombinedPass (camera: Camera, sampler.minFilter = sampler.magFilter = Filter.LINEAR; sampler.mipFilter = Filter.NONE; sampler.addressU = sampler.addressV = Address.CLAMP; - const computeView = new ComputeView(); - computeView.name = 'AOTexNearest'; - hbaoPass.addComputeView(inputRTName, computeView); + hbaoPass.addTexture(inputRTName, 'AOTexNearest'); } hbaoPass.addRenderTarget( diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index a65da10f866..15a3084e765 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -49,12 +49,11 @@ import { DescriptorSetData, LayoutGraphData, PipelineLayoutData, RenderPhaseData import { BasicPipeline, SceneVisitor } from './pipeline'; import { Blit, ClearView, ComputePass, ComputeSubpass, CopyPass, Dispatch, FormatView, ManagedBuffer, ManagedResource, ManagedTexture, MovePass, RasterPass, RasterSubpass, RaytracePass, RenderData, RenderGraph, RenderGraphVisitor, RenderQueue, RenderSwapchain, ResolvePass, ResourceDesc, - ResourceGraph, ResourceGraphVisitor, ResourceTraits, SceneData, SubresourceView } from './render-graph'; -import { AttachmentType, ComputeView, QueueHint, RasterView, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; + ResourceGraph, ResourceGraphVisitor, ResourceTraits, SceneData, SubresourceView, ComputeView, RasterView } from './render-graph'; +import { AttachmentType, QueueHint, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { PipelineUBO } from '../pipeline-ubo'; import { RenderInfo, RenderObject, WebSceneTask, WebSceneTransversal } from './web-scene'; import { WebSceneVisitor } from './web-scene-visitor'; -import { stringify } from './utils'; import { RenderAdditiveLightQueue } from '../render-additive-light-queue'; import { RenderShadowMapBatchedQueue } from '../render-shadow-map-batched-queue'; import { PlanarShadowQueue } from '../planar-shadow-queue'; diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 5b55811c14c..a705a5c139f 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -36,7 +36,7 @@ import { GlobalDSManager } from '../global-descriptor-set-manager'; import { Mat4, Quat, Vec2, Vec4 } from '../../core/math'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { AccessType, ComputeView, CopyPair, LightInfo, MovePair, QueueHint, RasterView, ResolvePair, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; +import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; @@ -157,14 +157,6 @@ export interface BasicRenderPassBuilder extends Setter { slotName: string, sampler?: Sampler | null, plane?: number): void; - /** - * @deprecated method will be removed in 3.9.0 - */ - addRasterView (name: string, view: RasterView): void; - /** - * @deprecated method will be removed in 3.9.0 - */ - addComputeView (name: string, view: ComputeView): void; addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; setViewport (viewport: Viewport): void; setVersion (name: string, version: number): void; @@ -264,10 +256,6 @@ export interface RenderSubpassBuilder extends Setter { name: string, accessType: AccessType, slotName: string): void; - /** - * @deprecated method will be removed in 3.9.0 - */ - addComputeView (name: string, view: ComputeView): void; setViewport (viewport: Viewport): void; addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; showStatistics: boolean; @@ -310,10 +298,6 @@ export interface ComputeSubpassBuilder extends Setter { name: string, accessType: AccessType, slotName: string): void; - /** - * @deprecated method will be removed in 3.9.0 - */ - addComputeView (name: string, view: ComputeView): void; addQueue (phaseName?: string): ComputeQueueBuilder; /** * @beta function signature might change @@ -361,10 +345,6 @@ export interface ComputePassBuilder extends Setter { accessType: AccessType, slotName: string): void; addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; - /** - * @deprecated method will be removed in 3.9.0 - */ - addComputeView (name: string, view: ComputeView): void; addQueue (phaseName?: string): ComputeQueueBuilder; /** * @beta function signature might change diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index 40cac35bb06..3051497dc36 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -31,11 +31,81 @@ import { AdjI, AdjacencyGraph, BidirectionalGraph, ComponentGraph, ED, InEI, MutableGraph, MutableReferenceGraph, NamedGraph, OutE, OutEI, PolymorphicGraph, PropertyGraph, PropertyMap, ReferenceGraph, UuidGraph, VertexListGraph, directional, parallel, reindexEdgeList, traversal } from './graph'; import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; -import { AccessFlagBit, Buffer, ClearFlagBit, Color, Format, Framebuffer, RenderPass, SampleCount, Sampler, SamplerInfo, ShaderStageFlagBit, Swapchain, Texture, TextureFlagBit, Viewport } from '../../gfx'; -import { ComputeView, CopyPair, LightInfo, MovePair, QueueHint, RasterView, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UploadPair } from './types'; +import { AccessFlagBit, Buffer, ClearFlagBit, Color, Format, Framebuffer, LoadOp, RenderPass, SampleCount, Sampler, SamplerInfo, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureFlagBit, Viewport } from '../../gfx'; +import { AccessType, AttachmentType, ClearValueType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UploadPair } from './types'; import { RenderScene } from '../../render-scene/core/render-scene'; import { RenderWindow } from '../../render-scene/core/render-window'; +export class ClearValue { + constructor (x = 0, y = 0, z = 0, w = 0) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + x: number; + y: number; + z: number; + w: number; +} + +export class RasterView { + constructor ( + slotName = '', + accessType: AccessType = AccessType.WRITE, + attachmentType: AttachmentType = AttachmentType.RENDER_TARGET, + loadOp: LoadOp = LoadOp.LOAD, + storeOp: StoreOp = StoreOp.STORE, + clearFlags: ClearFlagBit = ClearFlagBit.ALL, + clearColor: Color = new Color(), + shaderStageFlags: ShaderStageFlagBit = ShaderStageFlagBit.NONE, + ) { + this.slotName = slotName; + this.accessType = accessType; + this.attachmentType = attachmentType; + this.loadOp = loadOp; + this.storeOp = storeOp; + this.clearFlags = clearFlags; + this.clearColor = clearColor; + this.shaderStageFlags = shaderStageFlags; + } + slotName: string; + slotName1 = ''; + accessType: AccessType; + attachmentType: AttachmentType; + loadOp: LoadOp; + storeOp: StoreOp; + clearFlags: ClearFlagBit; + readonly clearColor: Color; + slotID = 0; + shaderStageFlags: ShaderStageFlagBit; +} + +export class ComputeView { + constructor ( + name = '', + accessType: AccessType = AccessType.READ, + clearFlags: ClearFlagBit = ClearFlagBit.NONE, + clearValueType: ClearValueType = ClearValueType.NONE, + clearValue: ClearValue = new ClearValue(), + shaderStageFlags: ShaderStageFlagBit = ShaderStageFlagBit.NONE, + ) { + this.name = name; + this.accessType = accessType; + this.clearFlags = clearFlags; + this.clearValueType = clearValueType; + this.clearValue = clearValue; + this.shaderStageFlags = shaderStageFlags; + } + name: string; + accessType: AccessType; + plane = 0; + clearFlags: ClearFlagBit; + clearValueType: ClearValueType; + readonly clearValue: ClearValue; + shaderStageFlags: ShaderStageFlagBit; +} + export class ResourceDesc { dimension: ResourceDimension = ResourceDimension.BUFFER; alignment = 0; diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index 74348dd2ee7..096b847abe7 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -28,10 +28,10 @@ * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= */ /* eslint-disable max-len */ -import { ClearFlagBit, Color, LoadOp, ResolveMode, ShaderStageFlagBit, StoreOp, Type, UniformBlock } from '../../gfx'; +import { ResolveMode, ShaderStageFlagBit, Type, UniformBlock } from '../../gfx'; import { Light } from '../../render-scene/scene'; import { OutputArchive, InputArchive } from './archive'; -import { saveColor, loadColor, saveUniformBlock, loadUniformBlock } from './serialization'; +import { saveUniformBlock, loadUniformBlock } from './serialization'; export enum UpdateFrequency { PER_INSTANCE, @@ -262,38 +262,6 @@ export function getAccessTypeName (e: AccessType): string { } } -export class RasterView { - constructor ( - slotName = '', - accessType: AccessType = AccessType.WRITE, - attachmentType: AttachmentType = AttachmentType.RENDER_TARGET, - loadOp: LoadOp = LoadOp.LOAD, - storeOp: StoreOp = StoreOp.STORE, - clearFlags: ClearFlagBit = ClearFlagBit.ALL, - clearColor: Color = new Color(), - shaderStageFlags: ShaderStageFlagBit = ShaderStageFlagBit.NONE, - ) { - this.slotName = slotName; - this.accessType = accessType; - this.attachmentType = attachmentType; - this.loadOp = loadOp; - this.storeOp = storeOp; - this.clearFlags = clearFlags; - this.clearColor = clearColor; - this.shaderStageFlags = shaderStageFlags; - } - slotName: string; - slotName1 = ''; - accessType: AccessType; - attachmentType: AttachmentType; - loadOp: LoadOp; - storeOp: StoreOp; - clearFlags: ClearFlagBit; - readonly clearColor: Color; - slotID = 0; - shaderStageFlags: ShaderStageFlagBit; -} - export enum ClearValueType { NONE, FLOAT_TYPE, @@ -313,44 +281,6 @@ export function getClearValueTypeName (e: ClearValueType): string { } } -export class ClearValue { - constructor (x = 0, y = 0, z = 0, w = 0) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - x: number; - y: number; - z: number; - w: number; -} - -export class ComputeView { - constructor ( - name = '', - accessType: AccessType = AccessType.READ, - clearFlags: ClearFlagBit = ClearFlagBit.NONE, - clearValueType: ClearValueType = ClearValueType.NONE, - clearValue: ClearValue = new ClearValue(), - shaderStageFlags: ShaderStageFlagBit = ShaderStageFlagBit.NONE, - ) { - this.name = name; - this.accessType = accessType; - this.clearFlags = clearFlags; - this.clearValueType = clearValueType; - this.clearValue = clearValue; - this.shaderStageFlags = shaderStageFlags; - } - name: string; - accessType: AccessType; - plane = 0; - clearFlags: ClearFlagBit; - clearValueType: ClearValueType; - readonly clearValue: ClearValue; - shaderStageFlags: ShaderStageFlagBit; -} - export class LightInfo { constructor (light: Light | null = null, level = 0) { this.light = light; @@ -566,66 +496,6 @@ export class PipelineStatistics { numInstancingUniformBlocks = 0; } -export function saveRasterView (ar: OutputArchive, v: RasterView) { - ar.writeString(v.slotName); - ar.writeString(v.slotName1); - ar.writeNumber(v.accessType); - ar.writeNumber(v.attachmentType); - ar.writeNumber(v.loadOp); - ar.writeNumber(v.storeOp); - ar.writeNumber(v.clearFlags); - saveColor(ar, v.clearColor); - ar.writeNumber(v.slotID); - ar.writeNumber(v.shaderStageFlags); -} - -export function loadRasterView (ar: InputArchive, v: RasterView) { - v.slotName = ar.readString(); - v.slotName1 = ar.readString(); - v.accessType = ar.readNumber(); - v.attachmentType = ar.readNumber(); - v.loadOp = ar.readNumber(); - v.storeOp = ar.readNumber(); - v.clearFlags = ar.readNumber(); - loadColor(ar, v.clearColor); - v.slotID = ar.readNumber(); - v.shaderStageFlags = ar.readNumber(); -} - -export function saveClearValue (ar: OutputArchive, v: ClearValue) { - ar.writeNumber(v.x); - ar.writeNumber(v.y); - ar.writeNumber(v.z); - ar.writeNumber(v.w); -} - -export function loadClearValue (ar: InputArchive, v: ClearValue) { - v.x = ar.readNumber(); - v.y = ar.readNumber(); - v.z = ar.readNumber(); - v.w = ar.readNumber(); -} - -export function saveComputeView (ar: OutputArchive, v: ComputeView) { - ar.writeString(v.name); - ar.writeNumber(v.accessType); - ar.writeNumber(v.plane); - ar.writeNumber(v.clearFlags); - ar.writeNumber(v.clearValueType); - saveClearValue(ar, v.clearValue); - ar.writeNumber(v.shaderStageFlags); -} - -export function loadComputeView (ar: InputArchive, v: ComputeView) { - v.name = ar.readString(); - v.accessType = ar.readNumber(); - v.plane = ar.readNumber(); - v.clearFlags = ar.readNumber(); - v.clearValueType = ar.readNumber(); - loadClearValue(ar, v.clearValue); - v.shaderStageFlags = ar.readNumber(); -} - export function saveLightInfo (ar: OutputArchive, v: LightInfo) { // skip, v.light: Light ar.writeNumber(v.level); diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index eacb55b0c32..58c24a9a5b2 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -27,8 +27,8 @@ import { systemInfo } from 'pal/system-info'; import { DEBUG } from 'internal:constants'; import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo } from '../../gfx'; import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy } from '../../core'; -import { AccessType, AttachmentType, ComputeView, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, RasterView, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; -import { Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; +import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; +import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities } from './pipeline'; import { PipelineSceneData } from '../pipeline-scene-data'; import { Model, Camera, ShadowType, CSMLevel, DirectionalLight, SpotLight, PCFType, Shadows } from '../../render-scene/scene'; @@ -932,12 +932,6 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB addStorageImage (name: string, accessType: AccessType, slotName: string): void { throw new Error('Method not implemented.'); } - addRasterView (name: string, view: RasterView): void { - throw new Error('Method not implemented.'); - } - addComputeView (name: string, view: ComputeView): void { - throw new Error('Method not implemented.'); - } setViewport (viewport: Viewport): void { throw new Error('Method not implemented.'); } @@ -986,23 +980,6 @@ export class WebRenderPassBuilder extends WebSetter implements BasicRenderPassBu setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void { throw new Error('Method not implemented.'); } - addRasterView (name: string, view: RasterView) { - this._pass.rasterViews.set(name, view); - } - addComputeView (name: string, view: ComputeView) { - if (DEBUG) { - assert(view.name); - assert(name && this._resourceGraph.contains(name)); - const descriptorName = view.name; - const descriptorID = this._layoutGraph.attributeIndex.get(descriptorName); - assert(descriptorID !== undefined); - } - if (this._pass.computeViews.has(name)) { - this._pass.computeViews.get(name)?.push(view); - } else { - this._pass.computeViews.set(name, [view]); - } - } setArrayBuffer (name: string, arrayBuffer: ArrayBuffer): void { throw new Error('Method not implemented.'); } @@ -1216,16 +1193,6 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit | undefined): void { throw new Error('Method not implemented.'); } - addComputeView (name: string, view: ComputeView) { - if (DEBUG) { - assert(name && this._resourceGraph.contains(name)); - } - if (this._pass.computeViews.has(name)) { - this._pass.computeViews.get(name)?.push(view); - } else { - this._pass.computeViews.set(name, [view]); - } - } addQueue (layoutName = 'default') { if (DEBUG) { const layoutId = this._layoutGraph.locateChild(this._layoutID, layoutName); diff --git a/cocos/rendering/post-process/utils/pass-context.ts b/cocos/rendering/post-process/utils/pass-context.ts index 51ca3199780..a2797270f49 100644 --- a/cocos/rendering/post-process/utils/pass-context.ts +++ b/cocos/rendering/post-process/utils/pass-context.ts @@ -1,6 +1,6 @@ import { EDITOR } from 'internal:constants'; -import { AccessType, AttachmentType, ComputeView, QueueHint, RasterView, ResourceResidency, SceneFlags } from '../../custom/types'; +import { QueueHint, ResourceResidency, SceneFlags } from '../../custom/types'; import { ClearFlagBit, Color, Format, LoadOp, Rect, StoreOp, Viewport } from '../../../gfx'; import { Pipeline, RenderPassBuilder } from '../../custom/pipeline'; import { Camera } from '../../../render-scene/scene'; @@ -164,9 +164,7 @@ export class PassContext { } setPassInput (inputName: string, shaderName: string) { if (this.ppl!.containsResource(inputName)) { - const computeView = new ComputeView(); - computeView.name = shaderName; - this.pass!.addComputeView(inputName, computeView); + this.pass!.addTexture(inputName, shaderName); } return this; } diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index 75c10abf826..b60700a6e0e 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -107,7 +107,6 @@ class NativeRenderSubpassBuilderImpl : public NativeSetter { void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) /*implements*/; void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) /*implements*/; void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) /*implements*/; - void addComputeView(const ccstd::string &name, const ComputeView &view) /*implements*/; void setViewport(const gfx::Viewport &viewport) /*implements*/; RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) /*implements*/; bool getShowStatistics() const /*implements*/; @@ -242,9 +241,6 @@ class NativeRenderSubpassBuilder final : public RenderSubpassBuilder, public Nat void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override { NativeRenderSubpassBuilderImpl::addStorageImage(name, accessType, slotName); } - void addComputeView(const ccstd::string &name, const ComputeView &view) override { - NativeRenderSubpassBuilderImpl::addComputeView(name, view); - } void setViewport(const gfx::Viewport &viewport) override { NativeRenderSubpassBuilderImpl::setViewport(viewport); } @@ -329,9 +325,6 @@ class NativeMultisampleRenderSubpassBuilder final : public MultisampleRenderSubp void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override { NativeRenderSubpassBuilderImpl::addStorageImage(name, accessType, slotName); } - void addComputeView(const ccstd::string &name, const ComputeView &view) override { - NativeRenderSubpassBuilderImpl::addComputeView(name, view); - } void setViewport(const gfx::Viewport &viewport) override { NativeRenderSubpassBuilderImpl::setViewport(viewport); } @@ -408,7 +401,6 @@ class NativeComputeSubpassBuilder final : public ComputeSubpassBuilder, public N void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) override; void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; - void addComputeView(const ccstd::string &name, const ComputeView &view) override; ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) override; void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) override; }; @@ -468,8 +460,6 @@ class NativeRenderPassBuilder final : public RenderPassBuilder, public NativeSet void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override; void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) override; void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) override; - void addRasterView(const ccstd::string &name, const RasterView &view) override; - void addComputeView(const ccstd::string &name, const ComputeView &view) override; RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) override; void setViewport(const gfx::Viewport &viewport) override; void setVersion(const ccstd::string &name, uint64_t version) override; @@ -596,7 +586,6 @@ class NativeComputePassBuilder final : public ComputePassBuilder, public NativeS void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) override; - void addComputeView(const ccstd::string &name, const ComputeView &view) override; ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) override; void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) override; }; diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index b850b5cfd06..97bc3089a2e 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -466,11 +466,105 @@ void NativeRenderPassBuilder::addDepthStencil( stencil); } +namespace { + +void addComputeView(NativeRenderPassBuilder &builder, const ccstd::string &name, const ComputeView &view) { + CC_EXPECTS(!name.empty()); + CC_EXPECTS(!view.name.empty()); + auto &pass = get(RasterPassTag{}, builder.nodeID, *builder.renderGraph); + auto iter = pass.computeViews.find(name.c_str()); + if (iter == pass.computeViews.end()) { + bool added = false; + std::tie(iter, added) = pass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); +} + +void addComputeView(NativeComputePassBuilder &builder, const ccstd::string &name, const ComputeView &view) { + CC_EXPECTS(!name.empty()); + CC_EXPECTS(!view.name.empty()); + auto &pass = get(ComputeTag{}, builder.nodeID, *builder.renderGraph); + auto iter = pass.computeViews.find(name.c_str()); + if (iter == pass.computeViews.end()) { + bool added = false; + std::tie(iter, added) = pass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); +} + +template +void addComputeViewImpl( + const ccstd::string &name, const ComputeView &view, + RenderGraph::vertex_descriptor subpassID, + RenderGraph &renderGraph) { + CC_EXPECTS(!name.empty()); + CC_EXPECTS(!view.name.empty()); + auto &subpass = get(Tag{}, subpassID, renderGraph); + const auto passID = parent(subpassID, renderGraph); + CC_EXPECTS(passID != RenderGraph::null_vertex()); + CC_EXPECTS(holds(passID, renderGraph)); + auto &pass = get(RasterPassTag{}, passID, renderGraph); + CC_EXPECTS(subpass.subpassID < num_vertices(pass.subpassGraph)); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + CC_EXPECTS(subpass.computeViews.size() == subpassData.computeViews.size()); + { + auto iter = subpassData.computeViews.find(name.c_str()); + if (iter == subpassData.computeViews.end()) { + bool added = false; + std::tie(iter, added) = subpassData.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); + } + { + auto iter = subpass.computeViews.find(name.c_str()); + if (iter == subpass.computeViews.end()) { + bool added = false; + std::tie(iter, added) = subpass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); + } + CC_ENSURES(subpass.computeViews.size() == subpassData.computeViews.size()); + CC_ENSURES(subpass.computeViews.find(std::string_view{name}) != subpass.computeViews.end()); + CC_ENSURES(subpassData.computeViews.find(std::string_view{name}) != subpassData.computeViews.end()); + CC_ENSURES(subpass.computeViews.find(std::string_view{name})->second.size() == + subpassData.computeViews.find(std::string_view{name})->second.size()); +} + +void addComputeView( + NativeRenderSubpassBuilderImpl &builder, + const ccstd::string &name, const ComputeView &view) { + addComputeViewImpl(name, view, builder.nodeID, *builder.renderGraph); +} + +void addComputeView( + NativeComputeSubpassBuilder &builder, const ccstd::string &name, const ComputeView &view) { + addComputeViewImpl(name, view, builder.nodeID, *builder.renderGraph); +} + +} // namespace + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) void NativeRenderPassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -493,6 +587,7 @@ void NativeRenderPassBuilder::addTexture( void NativeRenderPassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -507,6 +602,7 @@ void NativeRenderPassBuilder::addStorageBuffer( void NativeRenderPassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -544,33 +640,6 @@ void NativeRenderPassBuilder::setCustomShaderStages( } } -void NativeRenderPassBuilder::addRasterView(const ccstd::string &name, const RasterView &view) { - auto &pass = get(RasterPassTag{}, nodeID, *renderGraph); - auto slotID = static_cast(pass.rasterViews.size()); - auto res = pass.rasterViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple(view)); - CC_ENSURES(res.second); - res.first->second.slotID = slotID; -} - -void NativeRenderPassBuilder::addComputeView(const ccstd::string &name, const ComputeView &view) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &pass = get(RasterPassTag{}, nodeID, *renderGraph); - auto iter = pass.computeViews.find(name.c_str()); - if (iter == pass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = pass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); -} - bool NativeRenderPassBuilder::getShowStatistics() const { const auto &pass = get(RasterPassTag{}, nodeID, *renderGraph); return pass.showStatistics; @@ -652,52 +721,6 @@ void addRasterViewImpl( CC_ENSURES(subpass.rasterViews.size() == subpassData.rasterViews.size()); } -template -void addComputeViewImpl( - const ccstd::string &name, const ComputeView &view, - RenderGraph::vertex_descriptor subpassID, - RenderGraph &renderGraph) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &subpass = get(Tag{}, subpassID, renderGraph); - const auto passID = parent(subpassID, renderGraph); - CC_EXPECTS(passID != RenderGraph::null_vertex()); - CC_EXPECTS(holds(passID, renderGraph)); - auto &pass = get(RasterPassTag{}, passID, renderGraph); - CC_EXPECTS(subpass.subpassID < num_vertices(pass.subpassGraph)); - auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); - CC_EXPECTS(subpass.computeViews.size() == subpassData.computeViews.size()); - { - auto iter = subpassData.computeViews.find(name.c_str()); - if (iter == subpassData.computeViews.end()) { - bool added = false; - std::tie(iter, added) = subpassData.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); - } - { - auto iter = subpass.computeViews.find(name.c_str()); - if (iter == subpass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = subpass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); - } - CC_ENSURES(subpass.computeViews.size() == subpassData.computeViews.size()); - CC_ENSURES(subpass.computeViews.find(std::string_view{name}) != subpass.computeViews.end()); - CC_ENSURES(subpassData.computeViews.find(std::string_view{name}) != subpassData.computeViews.end()); - CC_ENSURES(subpass.computeViews.find(std::string_view{name})->second.size() == - subpassData.computeViews.find(std::string_view{name})->second.size()); -} - } // namespace void NativeRenderSubpassBuilderImpl::addRenderTarget( @@ -746,6 +769,7 @@ void NativeRenderSubpassBuilderImpl::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -768,6 +792,7 @@ void NativeRenderSubpassBuilderImpl::addTexture( void NativeRenderSubpassBuilderImpl::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -782,6 +807,7 @@ void NativeRenderSubpassBuilderImpl::addStorageBuffer( void NativeRenderSubpassBuilderImpl::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -848,10 +874,6 @@ void NativeRenderSubpassBuilderImpl::setCustomShaderStages( setSubpassResourceShaderStages(*renderGraph, nodeID, name, stageFlags); } -void NativeRenderSubpassBuilderImpl::addComputeView(const ccstd::string &name, const ComputeView &view) { - addComputeViewImpl(name, view, nodeID, *renderGraph); -} - void NativeRenderSubpassBuilderImpl::setViewport(const gfx::Viewport &viewport) { auto &subpass = get(RasterSubpassTag{}, nodeID, *renderGraph); subpass.viewport = viewport; @@ -937,6 +959,7 @@ void NativeComputeSubpassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -959,6 +982,7 @@ void NativeComputeSubpassBuilder::addTexture( void NativeComputeSubpassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -973,6 +997,7 @@ void NativeComputeSubpassBuilder::addStorageBuffer( void NativeComputeSubpassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -989,10 +1014,6 @@ void NativeComputeSubpassBuilder::setCustomShaderStages( setSubpassResourceShaderStages(*renderGraph, nodeID, name, stageFlags); } -void NativeComputeSubpassBuilder::addComputeView(const ccstd::string &name, const ComputeView &view) { - addComputeViewImpl(name, view, nodeID, *renderGraph); -} - ComputeQueueBuilder *NativeComputeSubpassBuilder::addQueue(const ccstd::string &phaseName) { CC_EXPECTS(!phaseName.empty()); CC_EXPECTS(layoutID != LayoutGraphData::null_vertex()); @@ -1662,6 +1683,7 @@ void NativeComputePassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1684,6 +1706,7 @@ void NativeComputePassBuilder::addTexture( void NativeComputePassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1698,6 +1721,7 @@ void NativeComputePassBuilder::addStorageBuffer( void NativeComputePassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { addComputeView( + *this, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1728,22 +1752,6 @@ void NativeComputePassBuilder::setCustomShaderStages( } } -void NativeComputePassBuilder::addComputeView(const ccstd::string &name, const ComputeView &view) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &pass = get(ComputeTag{}, nodeID, *renderGraph); - auto iter = pass.computeViews.find(name.c_str()); - if (iter == pass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = pass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); -} - ComputeQueueBuilder *NativeComputePassBuilder::addQueue(const ccstd::string &phaseName) { CC_EXPECTS(!phaseName.empty()); CC_EXPECTS(layoutID != LayoutGraphData::null_vertex()); diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h b/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h index 0aff9daaf2c..8f54ad52ca6 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h @@ -29,7 +29,6 @@ */ // clang-format off #pragma once -#include "cocos/base/std/hash/hash.h" #include "cocos/base/std/variant.h" #include "cocos/renderer/gfx-base/GFXDef-common.h" @@ -62,13 +61,8 @@ enum class SceneFlags : uint32_t; enum class LightingMode : uint32_t; enum class AttachmentType; enum class AccessType; - -struct RasterView; - enum class ClearValueType; -struct ClearValue; -struct ComputeView; struct LightInfo; enum class DescriptorTypeOrder; @@ -90,23 +84,4 @@ struct PipelineStatistics; } // namespace cc -namespace ccstd { - -template <> -struct hash { - hash_t operator()(const cc::render::RasterView& val) const noexcept; -}; - -template <> -struct hash { - hash_t operator()(const cc::render::ClearValue& val) const noexcept; -}; - -template <> -struct hash { - hash_t operator()(const cc::render::ComputeView& val) const noexcept; -}; - -} // namespace ccstd - // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp index e342b272501..9bb23563b0b 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp @@ -34,93 +34,6 @@ #include "cocos/renderer/pipeline/custom/RenderCommonTypes.h" #include "cocos/renderer/pipeline/custom/details/JsbConversion.h" -bool nativevalue_to_se(const cc::render::RasterView &from, se::Value &to, se::Object *ctx) { // NOLINT - se::HandleObject obj(se::Object::createPlainObject()); - se::Value tmp; - - nativevalue_to_se(from.slotName, tmp, ctx); - obj->setProperty("slotName", tmp); - - nativevalue_to_se(from.slotName1, tmp, ctx); - obj->setProperty("slotName1", tmp); - - nativevalue_to_se(from.accessType, tmp, ctx); - obj->setProperty("accessType", tmp); - - nativevalue_to_se(from.attachmentType, tmp, ctx); - obj->setProperty("attachmentType", tmp); - - nativevalue_to_se(from.loadOp, tmp, ctx); - obj->setProperty("loadOp", tmp); - - nativevalue_to_se(from.storeOp, tmp, ctx); - obj->setProperty("storeOp", tmp); - - nativevalue_to_se(from.clearFlags, tmp, ctx); - obj->setProperty("clearFlags", tmp); - - nativevalue_to_se(from.clearColor, tmp, ctx); - obj->setProperty("clearColor", tmp); - - nativevalue_to_se(from.slotID, tmp, ctx); - obj->setProperty("slotID", tmp); - - nativevalue_to_se(from.shaderStageFlags, tmp, ctx); - obj->setProperty("shaderStageFlags", tmp); - - to.setObject(obj); - return true; -} - -bool nativevalue_to_se(const cc::render::ClearValue &from, se::Value &to, se::Object *ctx) { // NOLINT - se::HandleObject obj(se::Object::createPlainObject()); - se::Value tmp; - - nativevalue_to_se(from.x, tmp, ctx); - obj->setProperty("x", tmp); - - nativevalue_to_se(from.y, tmp, ctx); - obj->setProperty("y", tmp); - - nativevalue_to_se(from.z, tmp, ctx); - obj->setProperty("z", tmp); - - nativevalue_to_se(from.w, tmp, ctx); - obj->setProperty("w", tmp); - - to.setObject(obj); - return true; -} - -bool nativevalue_to_se(const cc::render::ComputeView &from, se::Value &to, se::Object *ctx) { // NOLINT - se::HandleObject obj(se::Object::createPlainObject()); - se::Value tmp; - - nativevalue_to_se(from.name, tmp, ctx); - obj->setProperty("name", tmp); - - nativevalue_to_se(from.accessType, tmp, ctx); - obj->setProperty("accessType", tmp); - - nativevalue_to_se(from.plane, tmp, ctx); - obj->setProperty("plane", tmp); - - nativevalue_to_se(from.clearFlags, tmp, ctx); - obj->setProperty("clearFlags", tmp); - - nativevalue_to_se(from.clearValueType, tmp, ctx); - obj->setProperty("clearValueType", tmp); - - nativevalue_to_se(from.clearValue, tmp, ctx); - obj->setProperty("clearValue", tmp); - - nativevalue_to_se(from.shaderStageFlags, tmp, ctx); - obj->setProperty("shaderStageFlags", tmp); - - to.setObject(obj); - return true; -} - bool nativevalue_to_se(const cc::render::LightInfo &from, se::Value &to, se::Object *ctx) { // NOLINT se::HandleObject obj(se::Object::createPlainObject()); se::Value tmp; @@ -314,120 +227,6 @@ bool nativevalue_to_se(const cc::render::MovePair &from, se::Value &to, se::Obje return true; } -template <> -bool sevalue_to_native(const se::Value &from, cc::render::RasterView *to, se::Object *ctx) { // NOLINT - SE_PRECONDITION2(from.isObject(), false, " Convert parameter to RasterView failed !"); - - auto *obj = const_cast(from.toObject()); - bool ok = true; - se::Value field; - obj->getProperty("slotName", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->slotName), ctx); - } - obj->getProperty("slotName1", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->slotName1), ctx); - } - obj->getProperty("accessType", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->accessType), ctx); - } - obj->getProperty("attachmentType", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->attachmentType), ctx); - } - obj->getProperty("loadOp", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->loadOp), ctx); - } - obj->getProperty("storeOp", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->storeOp), ctx); - } - obj->getProperty("clearFlags", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->clearFlags), ctx); - } - obj->getProperty("clearColor", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->clearColor), ctx); - } - obj->getProperty("slotID", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->slotID), ctx); - } - obj->getProperty("shaderStageFlags", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->shaderStageFlags), ctx); - } - return ok; -} - -template <> -bool sevalue_to_native(const se::Value &from, cc::render::ClearValue *to, se::Object *ctx) { // NOLINT - SE_PRECONDITION2(from.isObject(), false, " Convert parameter to ClearValue failed !"); - - auto *obj = const_cast(from.toObject()); - bool ok = true; - se::Value field; - obj->getProperty("x", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->x), ctx); - } - obj->getProperty("y", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->y), ctx); - } - obj->getProperty("z", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->z), ctx); - } - obj->getProperty("w", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->w), ctx); - } - return ok; -} - -template <> -bool sevalue_to_native(const se::Value &from, cc::render::ComputeView *to, se::Object *ctx) { // NOLINT - SE_PRECONDITION2(from.isObject(), false, " Convert parameter to ComputeView failed !"); - - auto *obj = const_cast(from.toObject()); - bool ok = true; - se::Value field; - obj->getProperty("name", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->name), ctx); - } - obj->getProperty("accessType", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->accessType), ctx); - } - obj->getProperty("plane", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->plane), ctx); - } - obj->getProperty("clearFlags", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->clearFlags), ctx); - } - obj->getProperty("clearValueType", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->clearValueType), ctx); - } - obj->getProperty("clearValue", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->clearValue), ctx); - } - obj->getProperty("shaderStageFlags", &field, true); - if(!field.isNullOrUndefined()) { - ok &= sevalue_to_native(field, &(to->shaderStageFlags), ctx); - } - return ok; -} - template <> bool sevalue_to_native(const se::Value &from, cc::render::LightInfo *to, se::Object *ctx) { // NOLINT SE_PRECONDITION2(from.isObject(), false, " Convert parameter to LightInfo failed !"); diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.h b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.h index 66c2aa31883..56b478fb565 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.h @@ -32,12 +32,6 @@ #include "cocos/bindings/manual/jsb_conversions.h" #include "cocos/renderer/pipeline/custom/RenderCommonFwd.h" -bool nativevalue_to_se(const cc::render::RasterView &from, se::Value &to, se::Object *ctx); // NOLINT - -bool nativevalue_to_se(const cc::render::ClearValue &from, se::Value &to, se::Object *ctx); // NOLINT - -bool nativevalue_to_se(const cc::render::ComputeView &from, se::Value &to, se::Object *ctx); // NOLINT - bool nativevalue_to_se(const cc::render::LightInfo &from, se::Value &to, se::Object *ctx); // NOLINT bool nativevalue_to_se(const cc::render::Descriptor &from, se::Value &to, se::Object *ctx); // NOLINT @@ -55,15 +49,6 @@ bool nativevalue_to_se(const cc::render::UploadPair &from, se::Value &to, se::Ob bool nativevalue_to_se(const cc::render::MovePair &from, se::Value &to, se::Object *ctx); // NOLINT // if function overload is used, android build fails -template <> -bool sevalue_to_native(const se::Value &from, cc::render::RasterView *to, se::Object *ctx); // NOLINT - -template <> -bool sevalue_to_native(const se::Value &from, cc::render::ClearValue *to, se::Object *ctx); // NOLINT - -template <> -bool sevalue_to_native(const se::Value &from, cc::render::ComputeView *to, se::Object *ctx); // NOLINT - template <> bool sevalue_to_native(const se::Value &from, cc::render::LightInfo *to, se::Object *ctx); // NOLINT diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonNames.h b/native/cocos/renderer/pipeline/custom/RenderCommonNames.h index d192cbd550a..51a31444204 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonNames.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonNames.h @@ -125,7 +125,6 @@ inline const char* getName(AccessType e) noexcept { } return ""; } -inline const char* getName(const RasterView& /*v*/) noexcept { return "RasterView"; } inline const char* getName(ClearValueType e) noexcept { switch (e) { case ClearValueType::NONE: return "NONE"; @@ -134,8 +133,6 @@ inline const char* getName(ClearValueType e) noexcept { } return ""; } -inline const char* getName(const ClearValue& /*v*/) noexcept { return "ClearValue"; } -inline const char* getName(const ComputeView& /*v*/) noexcept { return "ComputeView"; } inline const char* getName(const LightInfo& /*v*/) noexcept { return "LightInfo"; } inline const char* getName(DescriptorTypeOrder e) noexcept { switch (e) { diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h b/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h index d4b56222b3c..49fa456c4cd 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h @@ -37,66 +37,6 @@ namespace cc { namespace render { -inline void save(OutputArchive& ar, const RasterView& v) { - save(ar, v.slotName); - save(ar, v.slotName1); - save(ar, v.accessType); - save(ar, v.attachmentType); - save(ar, v.loadOp); - save(ar, v.storeOp); - save(ar, v.clearFlags); - save(ar, v.clearColor); - save(ar, v.slotID); - save(ar, v.shaderStageFlags); -} - -inline void load(InputArchive& ar, RasterView& v) { - load(ar, v.slotName); - load(ar, v.slotName1); - load(ar, v.accessType); - load(ar, v.attachmentType); - load(ar, v.loadOp); - load(ar, v.storeOp); - load(ar, v.clearFlags); - load(ar, v.clearColor); - load(ar, v.slotID); - load(ar, v.shaderStageFlags); -} - -inline void save(OutputArchive& ar, const ClearValue& v) { - save(ar, v.x); - save(ar, v.y); - save(ar, v.z); - save(ar, v.w); -} - -inline void load(InputArchive& ar, ClearValue& v) { - load(ar, v.x); - load(ar, v.y); - load(ar, v.z); - load(ar, v.w); -} - -inline void save(OutputArchive& ar, const ComputeView& v) { - save(ar, v.name); - save(ar, v.accessType); - save(ar, v.plane); - save(ar, v.clearFlags); - save(ar, v.clearValueType); - save(ar, v.clearValue); - save(ar, v.shaderStageFlags); -} - -inline void load(InputArchive& ar, ComputeView& v) { - load(ar, v.name); - load(ar, v.accessType); - load(ar, v.plane); - load(ar, v.clearFlags); - load(ar, v.clearValueType); - load(ar, v.clearValue); - load(ar, v.shaderStageFlags); -} - inline void save(OutputArchive& ar, const LightInfo& v) { // skip, light: IntrusivePtr save(ar, v.level); diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp index 6246f7a86a6..1f556cf1058 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp @@ -34,94 +34,6 @@ namespace cc { namespace render { -RasterView::RasterView(const allocator_type& alloc) noexcept -: slotName(alloc), - slotName1(alloc) {} - -RasterView::RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT -: slotName(std::move(slotNameIn), alloc), - slotName1(alloc), - accessType(accessTypeIn), - attachmentType(attachmentTypeIn), - loadOp(loadOpIn), - storeOp(storeOpIn), - clearFlags(clearFlagsIn), - clearColor(clearColorIn), - shaderStageFlags(shaderStageFlagsIn) {} - -RasterView::RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT -: slotName(std::move(slotNameIn), alloc), - slotName1(std::move(slotName1In), alloc), - accessType(accessTypeIn), - attachmentType(attachmentTypeIn), - loadOp(loadOpIn), - storeOp(storeOpIn), - clearFlags(clearFlagsIn), - clearColor(clearColorIn), - shaderStageFlags(shaderStageFlagsIn) {} - -RasterView::RasterView(RasterView&& rhs, const allocator_type& alloc) -: slotName(std::move(rhs.slotName), alloc), - slotName1(std::move(rhs.slotName1), alloc), - accessType(rhs.accessType), - attachmentType(rhs.attachmentType), - loadOp(rhs.loadOp), - storeOp(rhs.storeOp), - clearFlags(rhs.clearFlags), - clearColor(rhs.clearColor), - slotID(rhs.slotID), - shaderStageFlags(rhs.shaderStageFlags) {} - -RasterView::RasterView(RasterView const& rhs, const allocator_type& alloc) -: slotName(rhs.slotName, alloc), - slotName1(rhs.slotName1, alloc), - accessType(rhs.accessType), - attachmentType(rhs.attachmentType), - loadOp(rhs.loadOp), - storeOp(rhs.storeOp), - clearFlags(rhs.clearFlags), - clearColor(rhs.clearColor), - slotID(rhs.slotID), - shaderStageFlags(rhs.shaderStageFlags) {} - -ComputeView::ComputeView(const allocator_type& alloc) noexcept -: name(alloc) {} - -ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept -: name(std::move(nameIn), alloc), - accessType(accessTypeIn), - clearFlags(clearFlagsIn), - clearValueType(clearValueTypeIn), - clearValue(clearValueIn), - shaderStageFlags(shaderStageFlagsIn) {} - -ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, uint32_t planeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept -: name(std::move(nameIn), alloc), - accessType(accessTypeIn), - plane(planeIn), - clearFlags(clearFlagsIn), - clearValueType(clearValueTypeIn), - clearValue(clearValueIn), - shaderStageFlags(shaderStageFlagsIn) {} - -ComputeView::ComputeView(ComputeView&& rhs, const allocator_type& alloc) -: name(std::move(rhs.name), alloc), - accessType(rhs.accessType), - plane(rhs.plane), - clearFlags(rhs.clearFlags), - clearValueType(rhs.clearValueType), - clearValue(rhs.clearValue), - shaderStageFlags(rhs.shaderStageFlags) {} - -ComputeView::ComputeView(ComputeView const& rhs, const allocator_type& alloc) -: name(rhs.name, alloc), - accessType(rhs.accessType), - plane(rhs.plane), - clearFlags(rhs.clearFlags), - clearValueType(rhs.clearValueType), - clearValue(rhs.clearValue), - shaderStageFlags(rhs.shaderStageFlags) {} - ResolvePair::ResolvePair(const allocator_type& alloc) noexcept : source(alloc), target(alloc) {} diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index 5f7279d6aad..ce9584a0c78 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -32,7 +32,6 @@ #include "cocos/base/Ptr.h" #include "cocos/base/std/container/map.h" #include "cocos/base/std/container/string.h" -#include "cocos/base/std/hash/hash.h" #include "cocos/renderer/gfx-base/GFXDef-common.h" #include "cocos/renderer/pipeline/custom/RenderCommonFwd.h" #include "cocos/scene/Light.h" @@ -197,115 +196,12 @@ enum class AccessType { WRITE, }; -struct RasterView { - using allocator_type = boost::container::pmr::polymorphic_allocator; - allocator_type get_allocator() const noexcept { // NOLINT - return {slotName.get_allocator().resource()}; - } - - RasterView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT - RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; - RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; - RasterView(RasterView&& rhs, const allocator_type& alloc); - RasterView(RasterView const& rhs, const allocator_type& alloc); - - RasterView(RasterView&& rhs) noexcept = default; - RasterView(RasterView const& rhs) = delete; - RasterView& operator=(RasterView&& rhs) = default; - RasterView& operator=(RasterView const& rhs) = default; - - ccstd::pmr::string slotName; - ccstd::pmr::string slotName1; - AccessType accessType{AccessType::WRITE}; - AttachmentType attachmentType{AttachmentType::RENDER_TARGET}; - gfx::LoadOp loadOp{gfx::LoadOp::LOAD}; - gfx::StoreOp storeOp{gfx::StoreOp::STORE}; - gfx::ClearFlagBit clearFlags{gfx::ClearFlagBit::ALL}; - gfx::Color clearColor; - uint32_t slotID{0}; - gfx::ShaderStageFlagBit shaderStageFlags{gfx::ShaderStageFlagBit::NONE}; -}; - -inline bool operator==(const RasterView& lhs, const RasterView& rhs) noexcept { - return std::forward_as_tuple(lhs.slotName, lhs.slotName1, lhs.accessType, lhs.attachmentType, lhs.loadOp, lhs.storeOp, lhs.clearFlags, lhs.shaderStageFlags) == - std::forward_as_tuple(rhs.slotName, rhs.slotName1, rhs.accessType, rhs.attachmentType, rhs.loadOp, rhs.storeOp, rhs.clearFlags, rhs.shaderStageFlags); -} - -inline bool operator!=(const RasterView& lhs, const RasterView& rhs) noexcept { - return !(lhs == rhs); -} - enum class ClearValueType { NONE, FLOAT_TYPE, INT_TYPE, }; -struct ClearValue { - ClearValue() = default; - ClearValue(double xIn, double yIn, double zIn, double wIn) noexcept // NOLINT - : x(xIn), - y(yIn), - z(zIn), - w(wIn) {} - - double x{0}; - double y{0}; - double z{0}; - double w{0}; -}; - -inline bool operator==(const ClearValue& lhs, const ClearValue& rhs) noexcept { - return std::forward_as_tuple(lhs.x, lhs.y, lhs.z, lhs.w) == - std::forward_as_tuple(rhs.x, rhs.y, rhs.z, rhs.w); -} - -inline bool operator!=(const ClearValue& lhs, const ClearValue& rhs) noexcept { - return !(lhs == rhs); -} - -struct ComputeView { - using allocator_type = boost::container::pmr::polymorphic_allocator; - allocator_type get_allocator() const noexcept { // NOLINT - return {name.get_allocator().resource()}; - } - - ComputeView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT - ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; - ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, uint32_t planeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; - ComputeView(ComputeView&& rhs, const allocator_type& alloc); - ComputeView(ComputeView const& rhs, const allocator_type& alloc); - - ComputeView(ComputeView&& rhs) noexcept = default; - ComputeView(ComputeView const& rhs) = delete; - ComputeView& operator=(ComputeView&& rhs) = default; - ComputeView& operator=(ComputeView const& rhs) = default; - - bool isRead() const { - return accessType != AccessType::WRITE; - } - bool isWrite() const { - return accessType != AccessType::READ; - } - - ccstd::pmr::string name; - AccessType accessType{AccessType::READ}; - uint32_t plane{0}; - gfx::ClearFlagBit clearFlags{gfx::ClearFlagBit::NONE}; - ClearValueType clearValueType{ClearValueType::NONE}; - ClearValue clearValue; - gfx::ShaderStageFlagBit shaderStageFlags{gfx::ShaderStageFlagBit::NONE}; -}; - -inline bool operator==(const ComputeView& lhs, const ComputeView& rhs) noexcept { - return std::forward_as_tuple(lhs.name, lhs.accessType, lhs.plane, lhs.clearFlags, lhs.clearValueType, lhs.shaderStageFlags) == - std::forward_as_tuple(rhs.name, rhs.accessType, rhs.plane, rhs.clearFlags, rhs.clearValueType, rhs.shaderStageFlags); -} - -inline bool operator!=(const ComputeView& lhs, const ComputeView& rhs) noexcept { - return !(lhs == rhs); -} - struct LightInfo { LightInfo() = default; LightInfo(IntrusivePtr lightIn, uint32_t levelIn) noexcept @@ -521,41 +417,4 @@ struct PipelineStatistics { } // namespace cc -namespace ccstd { - -inline hash_t hash::operator()(const cc::render::RasterView& val) const noexcept { - hash_t seed = 0; - hash_combine(seed, val.slotName); - hash_combine(seed, val.slotName1); - hash_combine(seed, val.accessType); - hash_combine(seed, val.attachmentType); - hash_combine(seed, val.loadOp); - hash_combine(seed, val.storeOp); - hash_combine(seed, val.clearFlags); - hash_combine(seed, val.shaderStageFlags); - return seed; -} - -inline hash_t hash::operator()(const cc::render::ClearValue& val) const noexcept { - hash_t seed = 0; - hash_combine(seed, val.x); - hash_combine(seed, val.y); - hash_combine(seed, val.z); - hash_combine(seed, val.w); - return seed; -} - -inline hash_t hash::operator()(const cc::render::ComputeView& val) const noexcept { - hash_t seed = 0; - hash_combine(seed, val.name); - hash_combine(seed, val.accessType); - hash_combine(seed, val.plane); - hash_combine(seed, val.clearFlags); - hash_combine(seed, val.clearValueType); - hash_combine(seed, val.shaderStageFlags); - return seed; -} - -} // namespace ccstd - // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphFwd.h b/native/cocos/renderer/pipeline/custom/RenderGraphFwd.h index 95483b4ad7e..0ec6698a935 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphFwd.h @@ -38,6 +38,9 @@ namespace cc { namespace render { +struct ClearValue; +struct RasterView; +struct ComputeView; struct ResourceDesc; struct ResourceTraits; struct RenderSwapchain; @@ -89,6 +92,21 @@ struct RenderGraph; namespace ccstd { +template <> +struct hash { + hash_t operator()(const cc::render::ClearValue& val) const noexcept; +}; + +template <> +struct hash { + hash_t operator()(const cc::render::RasterView& val) const noexcept; +}; + +template <> +struct hash { + hash_t operator()(const cc::render::ComputeView& val) const noexcept; +}; + template <> struct hash { hash_t operator()(const cc::render::Subpass& val) const noexcept; diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp index 0a7970dc992..0d6236eb388 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp @@ -34,6 +34,94 @@ namespace cc { namespace render { +RasterView::RasterView(const allocator_type& alloc) noexcept +: slotName(alloc), + slotName1(alloc) {} + +RasterView::RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT +: slotName(std::move(slotNameIn), alloc), + slotName1(alloc), + accessType(accessTypeIn), + attachmentType(attachmentTypeIn), + loadOp(loadOpIn), + storeOp(storeOpIn), + clearFlags(clearFlagsIn), + clearColor(clearColorIn), + shaderStageFlags(shaderStageFlagsIn) {} + +RasterView::RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept // NOLINT +: slotName(std::move(slotNameIn), alloc), + slotName1(std::move(slotName1In), alloc), + accessType(accessTypeIn), + attachmentType(attachmentTypeIn), + loadOp(loadOpIn), + storeOp(storeOpIn), + clearFlags(clearFlagsIn), + clearColor(clearColorIn), + shaderStageFlags(shaderStageFlagsIn) {} + +RasterView::RasterView(RasterView&& rhs, const allocator_type& alloc) +: slotName(std::move(rhs.slotName), alloc), + slotName1(std::move(rhs.slotName1), alloc), + accessType(rhs.accessType), + attachmentType(rhs.attachmentType), + loadOp(rhs.loadOp), + storeOp(rhs.storeOp), + clearFlags(rhs.clearFlags), + clearColor(rhs.clearColor), + slotID(rhs.slotID), + shaderStageFlags(rhs.shaderStageFlags) {} + +RasterView::RasterView(RasterView const& rhs, const allocator_type& alloc) +: slotName(rhs.slotName, alloc), + slotName1(rhs.slotName1, alloc), + accessType(rhs.accessType), + attachmentType(rhs.attachmentType), + loadOp(rhs.loadOp), + storeOp(rhs.storeOp), + clearFlags(rhs.clearFlags), + clearColor(rhs.clearColor), + slotID(rhs.slotID), + shaderStageFlags(rhs.shaderStageFlags) {} + +ComputeView::ComputeView(const allocator_type& alloc) noexcept +: name(alloc) {} + +ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept +: name(std::move(nameIn), alloc), + accessType(accessTypeIn), + clearFlags(clearFlagsIn), + clearValueType(clearValueTypeIn), + clearValue(clearValueIn), + shaderStageFlags(shaderStageFlagsIn) {} + +ComputeView::ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, uint32_t planeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc) noexcept +: name(std::move(nameIn), alloc), + accessType(accessTypeIn), + plane(planeIn), + clearFlags(clearFlagsIn), + clearValueType(clearValueTypeIn), + clearValue(clearValueIn), + shaderStageFlags(shaderStageFlagsIn) {} + +ComputeView::ComputeView(ComputeView&& rhs, const allocator_type& alloc) +: name(std::move(rhs.name), alloc), + accessType(rhs.accessType), + plane(rhs.plane), + clearFlags(rhs.clearFlags), + clearValueType(rhs.clearValueType), + clearValue(rhs.clearValue), + shaderStageFlags(rhs.shaderStageFlags) {} + +ComputeView::ComputeView(ComputeView const& rhs, const allocator_type& alloc) +: name(rhs.name, alloc), + accessType(rhs.accessType), + plane(rhs.plane), + clearFlags(rhs.clearFlags), + clearValueType(rhs.clearValueType), + clearValue(rhs.clearValue), + shaderStageFlags(rhs.shaderStageFlags) {} + Subpass::Subpass(const allocator_type& alloc) noexcept : rasterViews(alloc), computeViews(alloc) {} diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index cb5c0baeb23..d0f7e0aa9f7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -55,6 +55,109 @@ namespace cc { namespace render { +struct ClearValue { + ClearValue() = default; + ClearValue(double xIn, double yIn, double zIn, double wIn) noexcept // NOLINT + : x(xIn), + y(yIn), + z(zIn), + w(wIn) {} + + double x{0}; + double y{0}; + double z{0}; + double w{0}; +}; + +inline bool operator==(const ClearValue& lhs, const ClearValue& rhs) noexcept { + return std::forward_as_tuple(lhs.x, lhs.y, lhs.z, lhs.w) == + std::forward_as_tuple(rhs.x, rhs.y, rhs.z, rhs.w); +} + +inline bool operator!=(const ClearValue& lhs, const ClearValue& rhs) noexcept { + return !(lhs == rhs); +} + +struct RasterView { + using allocator_type = boost::container::pmr::polymorphic_allocator; + allocator_type get_allocator() const noexcept { // NOLINT + return {slotName.get_allocator().resource()}; + } + + RasterView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT + RasterView(ccstd::pmr::string slotNameIn, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + RasterView(ccstd::pmr::string slotNameIn, ccstd::pmr::string slotName1In, AccessType accessTypeIn, AttachmentType attachmentTypeIn, gfx::LoadOp loadOpIn, gfx::StoreOp storeOpIn, gfx::ClearFlagBit clearFlagsIn, gfx::Color clearColorIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + RasterView(RasterView&& rhs, const allocator_type& alloc); + RasterView(RasterView const& rhs, const allocator_type& alloc); + + RasterView(RasterView&& rhs) noexcept = default; + RasterView(RasterView const& rhs) = delete; + RasterView& operator=(RasterView&& rhs) = default; + RasterView& operator=(RasterView const& rhs) = default; + + ccstd::pmr::string slotName; + ccstd::pmr::string slotName1; + AccessType accessType{AccessType::WRITE}; + AttachmentType attachmentType{AttachmentType::RENDER_TARGET}; + gfx::LoadOp loadOp{gfx::LoadOp::LOAD}; + gfx::StoreOp storeOp{gfx::StoreOp::STORE}; + gfx::ClearFlagBit clearFlags{gfx::ClearFlagBit::ALL}; + gfx::Color clearColor; + uint32_t slotID{0}; + gfx::ShaderStageFlagBit shaderStageFlags{gfx::ShaderStageFlagBit::NONE}; +}; + +inline bool operator==(const RasterView& lhs, const RasterView& rhs) noexcept { + return std::forward_as_tuple(lhs.slotName, lhs.slotName1, lhs.accessType, lhs.attachmentType, lhs.loadOp, lhs.storeOp, lhs.clearFlags, lhs.shaderStageFlags) == + std::forward_as_tuple(rhs.slotName, rhs.slotName1, rhs.accessType, rhs.attachmentType, rhs.loadOp, rhs.storeOp, rhs.clearFlags, rhs.shaderStageFlags); +} + +inline bool operator!=(const RasterView& lhs, const RasterView& rhs) noexcept { + return !(lhs == rhs); +} + +struct ComputeView { + using allocator_type = boost::container::pmr::polymorphic_allocator; + allocator_type get_allocator() const noexcept { // NOLINT + return {name.get_allocator().resource()}; + } + + ComputeView(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT + ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + ComputeView(ccstd::pmr::string nameIn, AccessType accessTypeIn, uint32_t planeIn, gfx::ClearFlagBit clearFlagsIn, ClearValueType clearValueTypeIn, ClearValue clearValueIn, gfx::ShaderStageFlagBit shaderStageFlagsIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + ComputeView(ComputeView&& rhs, const allocator_type& alloc); + ComputeView(ComputeView const& rhs, const allocator_type& alloc); + + ComputeView(ComputeView&& rhs) noexcept = default; + ComputeView(ComputeView const& rhs) = delete; + ComputeView& operator=(ComputeView&& rhs) = default; + ComputeView& operator=(ComputeView const& rhs) = default; + + bool isRead() const { + return accessType != AccessType::WRITE; + } + bool isWrite() const { + return accessType != AccessType::READ; + } + + ccstd::pmr::string name; + AccessType accessType{AccessType::READ}; + uint32_t plane{0}; + gfx::ClearFlagBit clearFlags{gfx::ClearFlagBit::NONE}; + ClearValueType clearValueType{ClearValueType::NONE}; + ClearValue clearValue; + gfx::ShaderStageFlagBit shaderStageFlags{gfx::ShaderStageFlagBit::NONE}; +}; + +inline bool operator==(const ComputeView& lhs, const ComputeView& rhs) noexcept { + return std::forward_as_tuple(lhs.name, lhs.accessType, lhs.plane, lhs.clearFlags, lhs.clearValueType, lhs.shaderStageFlags) == + std::forward_as_tuple(rhs.name, rhs.accessType, rhs.plane, rhs.clearFlags, rhs.clearValueType, rhs.shaderStageFlags); +} + +inline bool operator!=(const ComputeView& lhs, const ComputeView& rhs) noexcept { + return !(lhs == rhs); +} + struct ResourceDesc { ResourceDimension dimension{ResourceDimension::BUFFER}; uint32_t alignment{0}; @@ -1028,6 +1131,39 @@ struct RenderGraph { namespace ccstd { +inline hash_t hash::operator()(const cc::render::ClearValue& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.x); + hash_combine(seed, val.y); + hash_combine(seed, val.z); + hash_combine(seed, val.w); + return seed; +} + +inline hash_t hash::operator()(const cc::render::RasterView& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.slotName); + hash_combine(seed, val.slotName1); + hash_combine(seed, val.accessType); + hash_combine(seed, val.attachmentType); + hash_combine(seed, val.loadOp); + hash_combine(seed, val.storeOp); + hash_combine(seed, val.clearFlags); + hash_combine(seed, val.shaderStageFlags); + return seed; +} + +inline hash_t hash::operator()(const cc::render::ComputeView& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.name); + hash_combine(seed, val.accessType); + hash_combine(seed, val.plane); + hash_combine(seed, val.clearFlags); + hash_combine(seed, val.clearValueType); + hash_combine(seed, val.shaderStageFlags); + return seed; +} + inline hash_t hash::operator()(const cc::render::Subpass& val) const noexcept { hash_t seed = 0; hash_combine(seed, val.rasterViews); diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index cde05b114d7..0c404938bbd 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -228,14 +228,6 @@ class BasicRenderPassBuilder : public Setter { virtual void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) = 0; virtual void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) = 0; virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual void addRasterView(const ccstd::string &name, const RasterView &view) = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual void addComputeView(const ccstd::string &name, const ComputeView &view) = 0; virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; virtual void setViewport(const gfx::Viewport &viewport) = 0; virtual void setVersion(const ccstd::string &name, uint64_t version) = 0; @@ -335,10 +327,6 @@ class RenderSubpassBuilder : public Setter { virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual void addComputeView(const ccstd::string &name, const ComputeView &view) = 0; virtual void setViewport(const gfx::Viewport &viewport) = 0; virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; virtual bool getShowStatistics() const = 0; @@ -429,10 +417,6 @@ class ComputeSubpassBuilder : public Setter { virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual void addComputeView(const ccstd::string &name, const ComputeView &view) = 0; virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** * @beta function signature might change @@ -482,10 +466,6 @@ class ComputePassBuilder : public Setter { virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual void addComputeView(const ccstd::string &name, const ComputeView &view) = 0; virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** * @beta function signature might change From 6aabfb7577d654eb6c4fba1e3212f428df288c33 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 15 Jun 2023 11:22:27 +0800 Subject: [PATCH 08/57] fix typo --- native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp index 03924775695..4082c070baf 100644 --- a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp @@ -1264,7 +1264,7 @@ void NativeProgramLibrary::addEffect(const EffectAsset *effectAssetIn) { const auto subpassOrPassID = subpassID == INVALID_ID ? passID : subpassID; const auto &srcShaderInfo = *pShaderInfo; CC_ENSURES(subpassOrPassID != INVALID_ID && phaseID != INVALID_ID); - const auto &passLayout = get(LayoutGraphData::LayoutTag{}, lg, subpassOrPassID); + const auto &passLayout = get(LayoutGraphData::LayoutTag{}, lg, passID); const auto &phaseLayout = get(LayoutGraphData::LayoutTag{}, lg, subpassOrPassID); // programs From aeba1ffd6e498063e158806a55132415a5f40252 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 15 Jun 2023 12:02:01 +0800 Subject: [PATCH 09/57] fix typo --- .../cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp index 4082c070baf..1e45cad430f 100644 --- a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp @@ -1264,8 +1264,8 @@ void NativeProgramLibrary::addEffect(const EffectAsset *effectAssetIn) { const auto subpassOrPassID = subpassID == INVALID_ID ? passID : subpassID; const auto &srcShaderInfo = *pShaderInfo; CC_ENSURES(subpassOrPassID != INVALID_ID && phaseID != INVALID_ID); - const auto &passLayout = get(LayoutGraphData::LayoutTag{}, lg, passID); - const auto &phaseLayout = get(LayoutGraphData::LayoutTag{}, lg, subpassOrPassID); + const auto &passLayout = get(LayoutGraphData::LayoutTag{}, lg, subpassOrPassID); + const auto &phaseLayout = get(LayoutGraphData::LayoutTag{}, lg, phaseID); // programs auto iter = this->phases.find(phaseID); From a0bb559b7677020c7e70299d6949d981fdce2fc4 Mon Sep 17 00:00:00 2001 From: Zach Lee Date: Fri, 16 Jun 2023 10:05:37 +0800 Subject: [PATCH 10/57] deferred-pipeline (#141) --- cocos/rendering/custom/builtin-pipelines.ts | 43 +++- cocos/rendering/custom/define.ts | 109 +++++---- cocos/rendering/custom/pipeline-define.ts | 208 +++++++++++++---- .../post-process/passes/forward-pass.ts | 1 - .../assets/chunks/common/common-define.chunk | 5 +- .../chunks/common/math/coordinates.chunk | 6 + .../legacy/shading-cluster-additive.chunk | 35 +-- .../legacy/standard-surface-entry.chunk | 12 +- .../lighting-flow/common-flow.chunk | 16 +- .../model-functions/toon.chunk | 4 +- .../pipeline/deferred-fs.chunk | 15 +- .../module-functions/standard-fs.chunk | 6 +- .../surfaces/module-functions/toon-fs.chunk | 6 +- .../surfaces/module-functions/unlit-fs.chunk | 6 +- editor/assets/effects/advanced/eye.effect | 27 ++- editor/assets/effects/advanced/leaf.effect | 28 ++- .../effects/advanced/simple-skin.effect | 31 ++- editor/assets/effects/advanced/skin.effect | 16 +- editor/assets/effects/advanced/sky.effect | 12 +- editor/assets/effects/advanced/water.effect | 24 +- .../builtin-reflection-probe-preview.effect | 36 ++- editor/assets/effects/builtin-standard.effect | 29 ++- editor/assets/effects/builtin-terrain.effect | 8 +- editor/assets/effects/builtin-toon.effect | 19 +- editor/assets/effects/builtin-unlit.effect | 37 ++- editor/assets/effects/legacy/standard.effect | 21 +- editor/assets/effects/legacy/terrain.effect | 6 +- editor/assets/effects/legacy/toon.effect | 17 +- .../particles/builtin-billboard.effect | 35 +++ .../particles/builtin-particle-gpu.effect | 35 +++ .../particles/builtin-particle-trail.effect | 35 +++ .../builtin-particle-xr-trail.effect | 7 + .../effects/particles/builtin-particle.effect | 35 +++ .../effects/pipeline/cluster-build.effect | 19 +- .../effects/pipeline/cluster-culling.effect | 26 ++- .../effects/pipeline/deferred-lighting.effect | 129 +++++++++-- .../effects/pipeline/post-process.effect | 1 - editor/assets/effects/pipeline/skybox.effect | 11 +- .../dcc/imported-metallic-roughness.effect | 25 +- .../dcc/imported-specular-glossiness.effect | 34 ++- .../dcc/vat/houdini-fluid-v3-liquid.effect | 26 ++- .../util/dcc/vat/houdini-rigidbody-v2.effect | 32 ++- .../util/dcc/vat/houdini-softbody-v3.effect | 25 +- .../util/dcc/vat/zeno-fluid-liquid.effect | 32 ++- native/cocos/renderer/gfx-base/GFXBarrier.cpp | 10 +- native/cocos/renderer/gfx-base/GFXDevice.cpp | 12 + native/cocos/renderer/gfx-base/GFXDevice.h | 2 + .../cocos/renderer/gfx-gles2/GLES2Device.cpp | 7 +- .../renderer/gfx-gles3/GLES3Commands.cpp | 8 +- .../renderer/gfx-gles3/GLES3DescriptorSet.cpp | 19 +- .../renderer/gfx-metal/MTLCommandBuffer.mm | 8 +- .../gfx-metal/MTLComputeCommandEncoder.h | 8 +- .../cocos/renderer/gfx-metal/MTLGPUObjects.h | 3 + native/cocos/renderer/gfx-metal/MTLShader.mm | 2 +- native/cocos/renderer/gfx-metal/MTLUtils.mm | 8 + .../cocos/renderer/gfx-vulkan/VKCommands.cpp | 2 +- .../pipeline/custom/FrameGraphDispatcher.cpp | 127 +++++----- .../pipeline/custom/LayoutGraphUtils.cpp | 5 +- .../pipeline/custom/LayoutGraphUtils.h | 3 +- .../pipeline/custom/NativeExecutor.cpp | 48 ++-- .../pipeline/custom/NativePipeline.cpp | 2 +- .../pipeline/custom/NativeProgramLibrary.cpp | 2 +- .../renderer/pipeline/custom/test/test.h | 8 +- .../src/complicated_barrier_case.cpp | 80 +------ .../unit-test/src/simple_barrier_test.cpp | 2 +- .../src/simple_closed_barrier_test.cpp | 218 +++++++++--------- 66 files changed, 1300 insertions(+), 574 deletions(-) diff --git a/cocos/rendering/custom/builtin-pipelines.ts b/cocos/rendering/custom/builtin-pipelines.ts index 27353767c44..1bd2a739fb1 100644 --- a/cocos/rendering/custom/builtin-pipelines.ts +++ b/cocos/rendering/custom/builtin-pipelines.ts @@ -25,12 +25,33 @@ import { EDITOR } from 'internal:constants'; import { Camera, CameraUsage } from '../../render-scene/scene'; import { BasicPipeline, PipelineBuilder } from './pipeline'; -import { buildForwardPass, buildGBufferPass, buildLightingPass, buildPostprocessPass, buildUIPass } from './define'; +import { buildClusterPasses } from './define'; import { isUICamera } from './utils'; -import { prepareResource, setupForwardPass, setupForwardRes, setupReflectionProbePass, setupReflectionProbeRes, - updateForwardRes, updateReflectionProbeRes, CameraInfo, setupGBufferPass, - updateGBufferRes, setupGBufferRes, setupLightingPass, setupLightingRes, updateLightingRes, - setupPostprocessPass, setupPostprocessRes, updatePostprocessRes, setupUIPass, setupUIRes, updateUIRes } from './pipeline-define'; +import { + prepareResource, + setupForwardPass, + setupForwardRes, + setupReflectionProbePass, + setupReflectionProbeRes, + updateForwardRes, + updateReflectionProbeRes, + CameraInfo, + setupGBufferPass, + updateGBufferRes, + setupGBufferRes, + setupLightingPass, + setupLightingRes, + updateLightingRes, + setupPostprocessPass, + setupPostprocessRes, + updatePostprocessRes, + setupUIPass, + setupUIRes, + updateUIRes, + setupDeferredForward, + setupScenePassTiled, +} from './pipeline-define'; +import { Feature } from '../../gfx'; export class ForwardPipelineBuilder implements PipelineBuilder { public setup (cameras: Camera[], ppl: BasicPipeline): void { @@ -65,6 +86,9 @@ export class DeferredPipelineBuilder implements PipelineBuilder { continue; } ppl.update(camera); + const forceDisableCluster = false; + const useCluster = !forceDisableCluster && ppl.device.hasFeature(Feature.COMPUTE_SHADER); + const isGameView = camera.cameraUsage === CameraUsage.GAME || camera.cameraUsage === CameraUsage.GAME_VIEW; const info = prepareResource(ppl, camera, this.initResource, this.updateResource); @@ -73,12 +97,19 @@ export class DeferredPipelineBuilder implements PipelineBuilder { continue; } if (!isUICamera(camera)) { + if (useCluster) { + buildClusterPasses(camera, ppl); + } + // GBuffer Pass setupGBufferPass(ppl, info); // Lighting Pass - const lightInfo = setupLightingPass(ppl, info); + const lightInfo = setupLightingPass(ppl, info, useCluster); + // Deferred ForwardPass, for non-surface-shader material and transparent material + setupDeferredForward(ppl, info, lightInfo.rtName); // Postprocess setupPostprocessPass(ppl, info, lightInfo.rtName); + continue; } // render ui diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index a17e0c5c6e5..155caac77df 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -117,6 +117,8 @@ export function validPunctualLightsCulling (pipeline: BasicPipeline, camera: Cam validPunctualLights.push(light); } } + // array push not supported. + pipeline.pipelineSceneData.validPunctualLights = validPunctualLights; } const _cameras: Camera[] = []; @@ -800,18 +802,21 @@ export function buildGBufferPass (camera: Camera, export class LightingInfo { declare deferredLightingMaterial: Material; + public enableCluster: number; + private _init () { this.deferredLightingMaterial = new Material(); this.deferredLightingMaterial.name = 'builtin-deferred-material'; this.deferredLightingMaterial.initialize({ effectName: 'pipeline/deferred-lighting', - defines: { CC_RECEIVE_SHADOW: 1 }, + defines: { CC_ENABLE_CLUSTERED_LIGHT_CULLING: this.enableCluster, CC_RECEIVE_SHADOW: 1 }, }); for (let i = 0; i < this.deferredLightingMaterial.passes.length; ++i) { this.deferredLightingMaterial.passes[i].tryCompile(); } } - constructor () { + constructor (clusterEn: boolean) { + this.enableCluster = clusterEn ? 1 : 0; this._init(); } } @@ -821,7 +826,7 @@ let lightingInfo: LightingInfo; // deferred lighting pass export function buildLightingPass (camera: Camera, ppl: BasicPipeline, gBuffer: GBufferInfo) { if (!lightingInfo) { - lightingInfo = new LightingInfo(); + lightingInfo = new LightingInfo(false); } const cameraID = getCameraUniqueID(camera); const cameraName = `Camera${cameraID}`; @@ -831,13 +836,10 @@ export function buildLightingPass (camera: Camera, ppl: BasicPipeline, gBuffer: const height = area.height; const deferredLightingPassRTName = `deferredLightingPassRTName`; - const deferredLightingPassDS = `deferredLightingPassDS`; if (!ppl.containsResource(deferredLightingPassRTName)) { ppl.addRenderTarget(deferredLightingPassRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); - ppl.addDepthStencil(deferredLightingPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } ppl.updateRenderTarget(deferredLightingPassRTName, width, height); - ppl.updateDepthStencil(deferredLightingPassDS, width, height); // lighting pass const lightingPass = ppl.addRenderPass(width, height, 'deferred-lighting'); lightingPass.name = `CameraLightingPass${cameraID}`; @@ -853,10 +855,10 @@ export function buildLightingPass (camera: Camera, ppl: BasicPipeline, gBuffer: } } if (ppl.containsResource(gBuffer.color)) { - lightingPass.addTexture(gBuffer.color, 'gbuffer_albedoMap'); - lightingPass.addTexture(gBuffer.normal, 'gbuffer_normalMap'); - lightingPass.addTexture(gBuffer.emissive, 'gbuffer_emissiveMap'); - lightingPass.addTexture(gBuffer.ds, 'depth_stencil'); + lightingPass.addTexture(gBuffer.color, 'albedoMap'); + lightingPass.addTexture(gBuffer.normal, 'normalMap'); + lightingPass.addTexture(gBuffer.emissive, 'emissiveMap'); + lightingPass.addTexture(gBuffer.ds, 'depthStencil'); } const lightingClearColor = new Color(0, 0, 0, 0); if (camera.clearFlag & ClearFlagBit.COLOR) { @@ -872,7 +874,7 @@ export function buildLightingPass (camera: Camera, ppl: BasicPipeline, gBuffer: ); // lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, new LightInfo(), // SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); - return { rtName: deferredLightingPassRTName, dsName: deferredLightingPassDS }; + return { rtName: deferredLightingPassRTName }; } function getClearFlags (attachment: AttachmentType, clearFlag: ClearFlagBit, loadOp: LoadOp): ClearFlagBit { @@ -2006,9 +2008,9 @@ export function buildLightClusterBuildPass (camera: Camera, clusterData: Cluster const cameraID = getCameraUniqueID(camera); const clusterBufferName = `clusterBuffer${cameraID}`; - const clusterBufferSize = CLUSTER_COUNT * 2 * 4; + const clusterBufferSize = CLUSTER_COUNT * 2 * 4 * 4; if (!ppl.containsResource(clusterBufferName)) { - ppl.addStorageBuffer(clusterBufferName, Format.UNKNOWN, clusterBufferSize, ResourceResidency.PERSISTENT); + ppl.addStorageBuffer(clusterBufferName, Format.UNKNOWN, clusterBufferSize, ResourceResidency.MANAGED); } ppl.updateStorageBuffer(clusterBufferName, clusterBufferSize); @@ -2020,7 +2022,7 @@ export function buildLightClusterBuildPass (camera: Camera, clusterData: Cluster const width = camera.width * ppl.pipelineSceneData.shadingScale; const height = camera.height * ppl.pipelineSceneData.shadingScale; clusterPass.setVec4('cc_nearFar', new Vec4(camera.nearClip, camera.farClip, 0, 0)); - clusterPass.setVec4('cc_viewPort', new Vec4(width, height, width, height)); + clusterPass.setVec4('cc_viewPort', new Vec4(0, 0, width, height)); clusterPass.setVec4('cc_workGroup', new Vec4(CLUSTERS_X, CLUSTERS_Y, CLUSTERS_Z, 0)); clusterPass.setMat4('cc_matView', camera.matView); clusterPass.setMat4('cc_matProjInv', camera.matProjInv); @@ -2031,18 +2033,18 @@ export function buildLightClusterCullingPass (camera: Camera, clusterData: Clust const cameraID = getCameraUniqueID(camera); const clusterBufferName = `clusterBuffer${cameraID}`; const clusterLightBufferName = `clusterLightBuffer${cameraID}`; - const clusterGlobalIndexBufferName = `b_globalIndexBuffer${cameraID}`; - const clusterLightIndicesBufferName = `clusterLIghtIndicesBuffer${cameraID}`; + const clusterGlobalIndexBufferName = `globalIndexBuffer${cameraID}`; + const clusterLightIndicesBufferName = `clusterLightIndicesBuffer${cameraID}`; const clusterLightGridBufferName = `clusterLightGridBuffer${cameraID}`; // index buffer const lightIndexBufferSize = MAX_LIGHTS_PER_CLUSTER * CLUSTER_COUNT * 4; const lightGridBufferSize = CLUSTER_COUNT * 4 * 4; if (!ppl.containsResource(clusterLightIndicesBufferName)) { - ppl.addStorageBuffer(clusterLightIndicesBufferName, Format.UNKNOWN, lightIndexBufferSize, ResourceResidency.PERSISTENT); + ppl.addStorageBuffer(clusterLightIndicesBufferName, Format.UNKNOWN, lightIndexBufferSize, ResourceResidency.MANAGED); } if (!ppl.containsResource(clusterLightGridBufferName)) { - ppl.addStorageBuffer(clusterLightGridBufferName, Format.UNKNOWN, lightGridBufferSize, ResourceResidency.PERSISTENT); + ppl.addStorageBuffer(clusterLightGridBufferName, Format.UNKNOWN, lightGridBufferSize, ResourceResidency.MANAGED); } const clusterPass = ppl.addComputePass('cluster-culling-cs'); @@ -2063,44 +2065,23 @@ export function buildLightClusterCullingPass (camera: Camera, clusterData: Clust clusterPass.setMat4('cc_matProjInv', camera.matProjInv); } -export function buildLightData (camera: Camera, pipeline: BasicPipeline) { - validPunctualLightsCulling(pipeline, camera); +export function buildLightBuffer (size: number, floatPerLight: number, camera: Camera, pipeline: BasicPipeline) { + const buffer = new ArrayBuffer(size); + const view = new Float32Array(buffer); - // build cluster light data const data = pipeline.pipelineSceneData; - const validLightCountForBuffer = nextPow2(Math.max(data.validPunctualLights.length, 1)); - - const lightBufferStride = 16; // 4 * vec4 - const clusterLightBufferSize = validLightCountForBuffer * 4 * lightBufferStride; - const lightMeterScale = 10000.0; const exposure = camera.exposure; - const cameraID = getCameraUniqueID(camera); - const clusterLightBufferName = `clusterLightBuffer${cameraID}`; - const clusterGlobalIndexBufferName = `b_globalIndexBuffer${cameraID}`; - - const ppl = (pipeline as Pipeline); - if (!ppl.containsResource(clusterGlobalIndexBufferName)) { - ppl.addStorageBuffer(clusterGlobalIndexBufferName, Format.UNKNOWN, 4, ResourceResidency.PERSISTENT); - } - - if (!ppl.containsResource(clusterLightBufferName)) { - ppl.addStorageBuffer(clusterLightBufferName, Format.UNKNOWN, clusterLightBufferSize, ResourceResidency.PERSISTENT); - } - ppl.updateStorageBuffer(clusterLightBufferName, clusterLightBufferSize); - - const buffer = new ArrayBuffer(clusterLightBufferSize); - const view = new Float32Array(buffer); - // gather light data let index = 0; for (const light of data.validPunctualLights) { - const offset = index * lightBufferStride; + const offset = index * floatPerLight; const positionOffset = offset + 0; const colorOffset = offset + 4; const sizeRangeAngleOffset = offset + 8; const directionOffset = offset + 12; + const boundSizeOffset = offset + 16; let luminanceHDR = 0; let luminanceLDR = 0; @@ -2158,6 +2139,12 @@ export function buildLightData (camera: Camera, pipeline: BasicPipeline) { view[directionOffset + 1] = dir.y; view[directionOffset + 2] = dir.z; view[directionOffset + 3] = 0; + + const scale = directional.scale; + view[boundSizeOffset] = scale.x * 0.5; + view[boundSizeOffset + 1] = scale.y * 0.5; + view[boundSizeOffset + 2] = scale.z * 0.5; + view[boundSizeOffset + 3] = 0; } // position view[positionOffset] = position!.x; @@ -2182,6 +2169,38 @@ export function buildLightData (camera: Camera, pipeline: BasicPipeline) { } // last float of first light data view[3 * 4 + 3] = data.validPunctualLights.length; + return buffer; +} + +export function buildStandardLightData (camera: Camera, pipeline: BasicPipeline) { + validPunctualLightsCulling(pipeline, camera); +} + +export function buildClusterLightData (camera: Camera, pipeline: BasicPipeline) { + validPunctualLightsCulling(pipeline, camera); + + // build cluster light data + const data = pipeline.pipelineSceneData; + const validLightCountForBuffer = nextPow2(Math.max(data.validPunctualLights.length, 1)); + + const lightBufferFloatNum = 20; // 5 * vec4 + const clusterLightBufferSize = validLightCountForBuffer * 4 * lightBufferFloatNum; + + const cameraID = getCameraUniqueID(camera); + const clusterLightBufferName = `clusterLightBuffer${cameraID}`; + const clusterGlobalIndexBufferName = `globalIndexBuffer${cameraID}`; + + const ppl = (pipeline as Pipeline); + if (!ppl.containsResource(clusterGlobalIndexBufferName)) { + ppl.addStorageBuffer(clusterGlobalIndexBufferName, Format.UNKNOWN, 4, ResourceResidency.PERSISTENT); + } + + if (!ppl.containsResource(clusterLightBufferName)) { + ppl.addStorageBuffer(clusterLightBufferName, Format.UNKNOWN, clusterLightBufferSize, ResourceResidency.PERSISTENT); + } + ppl.updateStorageBuffer(clusterLightBufferName, clusterLightBufferSize); + + const buffer = buildLightBuffer(clusterLightBufferSize, lightBufferFloatNum, camera, pipeline); // global index buffer const globalIndexBuffer = new ArrayBuffer(4); @@ -2194,7 +2213,7 @@ export function buildLightData (camera: Camera, pipeline: BasicPipeline) { } export function buildClusterPasses (camera: Camera, pipeline: BasicPipeline) { - buildLightData(camera, pipeline); + buildClusterLightData(camera, pipeline); const ppl = (pipeline as Pipeline); if (!_clusterLightData) _clusterLightData = new ClusterLightData(); diff --git a/cocos/rendering/custom/pipeline-define.ts b/cocos/rendering/custom/pipeline-define.ts index 1db8f3c7489..b9693dc85ea 100644 --- a/cocos/rendering/custom/pipeline-define.ts +++ b/cocos/rendering/custom/pipeline-define.ts @@ -1,14 +1,31 @@ import { EDITOR } from 'internal:constants'; import { cclegacy } from '../../core'; -import { ClearFlagBit, Color, Format, LoadOp, StoreOp, Viewport } from '../../gfx'; +import { ClearFlagBit, Color, Format, LoadOp, ShaderStageFlagBit, StoreOp, Viewport } from '../../gfx'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Camera, Light, LightType, ProbeType, ReflectionProbe, ShadowType } from '../../render-scene/scene'; import { supportsR32FloatTexture } from '../define'; -import { AntiAliasing, GBufferInfo, getRTFormatBeforeToneMapping, LightingInfo, PostInfo, ShadowInfo, getLoadOpOfClearFlag, - getRenderArea, updateCameraUBO, validPunctualLightsCulling } from './define'; -import { BasicPipeline } from './pipeline'; -import { AttachmentType, LightInfo, QueueHint, ResourceResidency, SceneFlags } from './types'; -import { SRGBToLinear, getProfilerCamera } from '../pipeline-funcs'; +import { + GBufferInfo, + getCameraUniqueID, + getLoadOpOfClearFlag, + getRenderArea, + getRTFormatBeforeToneMapping, + LightingInfo, + PostInfo, + ShadowInfo, + updateCameraUBO, + validPunctualLightsCulling, +} from './define'; +import { BasicPipeline, Pipeline } from './pipeline'; +import { + AccessType, + AttachmentType, + LightInfo, + QueueHint, + ResourceResidency, + SceneFlags, +} from './types'; +import { getProfilerCamera, SRGBToLinear } from '../pipeline-funcs'; export class CameraInfo { constructor (camera: Camera, id: number, windowID: number, width: number, height: number) { @@ -50,9 +67,6 @@ export function prepareResource (ppl: BasicPipeline, camera: Camera, height = 1; } const windowID = prepareRenderWindow(camera); - if (info.width !== width || info.height !== height || info.windowID !== windowID) { - return info; - } updateResourceFunc(ppl, info); return info; } @@ -221,6 +235,34 @@ export function updateForwardRes (ppl: BasicPipeline, cameraInfo: CameraInfo, is ppl.updateDepthStencil(`ForwardDepthStencil${cameraInfo.id}`, width, height); } +export function setupDeferredForward (ppl: BasicPipeline, cameraInfo: CameraInfo, inputColor: string) { + const area = getRenderArea(cameraInfo.camera, cameraInfo.camera.window.width, cameraInfo.camera.window.height); + const width = area.width; + const height = area.height; + const forwardPass = ppl.addRenderPass(width, height, 'default'); + const camera = cameraInfo.camera; + forwardPass.addRenderTarget(inputColor, LoadOp.LOAD, StoreOp.STORE); + forwardPass.addDepthStencil(gBufferInfo.ds, LoadOp.LOAD, StoreOp.DISCARD); + + for (const dirShadowName of shadowInfo.mainLightShadowNames) { + if (ppl.containsResource(dirShadowName)) { + forwardPass.addTexture(dirShadowName, 'cc_shadowMap'); + } + } + for (const spotShadowName of shadowInfo.spotLightShadowNames) { + if (ppl.containsResource(spotShadowName)) { + forwardPass.addTexture(spotShadowName, 'cc_spotShadowMap'); + } + } + + forwardPass.addQueue(QueueHint.RENDER_OPAQUE, 'deferred-forward') + .addSceneOfCamera(camera, new LightInfo(), + SceneFlags.OPAQUE_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.CUTOUT_OBJECT + | SceneFlags.DEFAULT_LIGHTING | SceneFlags.DRAW_INSTANCING); + forwardPass.addQueue(QueueHint.RENDER_TRANSPARENT, 'deferred-forward') + .addSceneOfCamera(camera, new LightInfo(), SceneFlags.TRANSPARENT_OBJECT | SceneFlags.GEOMETRY); +} + export function setupForwardPass (ppl: BasicPipeline, cameraInfo: CameraInfo, isOffScreen = false, enabledAlpha = true) { if (EDITOR) { ppl.setMacroInt('CC_PIPELINE_TYPE', 0); @@ -260,6 +302,7 @@ export function setupForwardPass (ppl: BasicPipeline, cameraInfo: CameraInfo, is .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.CUTOUT_OBJECT | SceneFlags.DEFAULT_LIGHTING | SceneFlags.DRAW_INSTANCING); + let sceneFlags = SceneFlags.TRANSPARENT_OBJECT | SceneFlags.GEOMETRY; if (!isOffScreen) { sceneFlags |= SceneFlags.UI; @@ -283,7 +326,7 @@ export function buildReflectionProbeRes (ppl: BasicPipeline, probe: ReflectionPr if (!ppl.containsResource(probePassRTName)) { ppl.addRenderWindow(probePassRTName, Format.RGBA8, width, height, renderWindow); - ppl.addDepthStencil(probePassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.EXTERNAL); + ppl.addDepthStencil(probePassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } ppl.updateRenderWindow(probePassRTName, renderWindow); ppl.updateDepthStencil(probePassDSName, width, height); @@ -357,14 +400,14 @@ export function setupGBufferRes (ppl: BasicPipeline, info: CameraInfo) { const area = getRenderArea(camera, camera.window.width, camera.window.height); const width = area.width; const height = area.height; - const gBufferPassRTName = `gBufferPassColorCamera`; - const gBufferPassNormal = `gBufferPassNormal`; - const gBufferPassEmissive = `gBufferPassEmissive`; - const gBufferPassDSName = `gBufferPassDSCamera`; + const gBufferPassRTName = `gBufferPassColorCamera${info.id}`; + const gBufferPassNormal = `gBufferPassNormal${info.id}`; + const gBufferPassEmissive = `gBufferPassEmissive${info.id}`; + const gBufferPassDSName = `gBufferPassDSCamera${info.id}`; const colFormat = Format.RGBA16F; ppl.addRenderTarget(gBufferPassRTName, colFormat, width, height, ResourceResidency.MANAGED); - ppl.addRenderTarget(gBufferPassNormal, colFormat, width, height, ResourceResidency.MANAGED); ppl.addRenderTarget(gBufferPassEmissive, colFormat, width, height, ResourceResidency.MANAGED); + ppl.addRenderTarget(gBufferPassNormal, colFormat, width, height, ResourceResidency.MANAGED); ppl.addDepthStencil(gBufferPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); gBufferInfo.color = gBufferPassRTName; gBufferInfo.normal = gBufferPassNormal; @@ -377,16 +420,86 @@ export function updateGBufferRes (ppl: BasicPipeline, info: CameraInfo) { const area = getRenderArea(camera, camera.window.width, camera.window.height); const width = area.width; const height = area.height; - const gBufferPassRTName = `gBufferPassColorCamera`; - const gBufferPassNormal = `gBufferPassNormal`; - const gBufferPassEmissive = `gBufferPassEmissive`; - const gBufferPassDSName = `gBufferPassDSCamera`; + const gBufferPassRTName = `gBufferPassColorCamera${info.id}`; + const gBufferPassNormal = `gBufferPassNormal${info.id}`; + const gBufferPassEmissive = `gBufferPassEmissive${info.id}`; + const gBufferPassDSName = `gBufferPassDSCamera${info.id}`; ppl.updateRenderTarget(gBufferPassRTName, width, height); - ppl.updateRenderTarget(gBufferPassNormal, width, height); ppl.updateRenderTarget(gBufferPassEmissive, width, height); + ppl.updateRenderTarget(gBufferPassNormal, width, height); ppl.updateDepthStencil(gBufferPassDSName, width, height); } +const emptyColor = new Color(0, 0, 0, 0); +export function setupScenePassTiled (pipeline: BasicPipeline, info: CameraInfo, useCluster: boolean) { + if (!lightingInfo) { + lightingInfo = new LightingInfo(useCluster); + } + + const ppl = (pipeline as Pipeline); + const camera = info.camera; + const cameraID = getCameraUniqueID(camera); + const area = getRenderArea(camera, camera.window.width, camera.window.height); + const width = area.width; + const height = area.height; + const gBufferPassRTName = gBufferInfo.color; + const gBufferPassNormal = gBufferInfo.normal; + const gBufferPassEmissive = gBufferInfo.emissive; + const gBufferPassDSName = gBufferInfo.ds; + const scenePass = ppl.addRenderPass(width, height, 'deferred-scene-tiled'); + + // gbuffer subpass + const gBufferPass = scenePass.addRenderSubpass('gbuffer-tiled'); + gBufferPass.name = `CameraGBufferPass${info.id}`; + gBufferPass.setViewport(new Viewport(area.x, area.y, width, height)); + const rtColor = new Color(0, 0, 0, 0); + if (camera.clearFlag & ClearFlagBit.COLOR) { + if (ppl.pipelineSceneData.isHDR) { + SRGBToLinear(rtColor, camera.clearColor); + } else { + rtColor.x = camera.clearColor.x; + rtColor.y = camera.clearColor.y; + rtColor.z = camera.clearColor.z; + } + } + gBufferPass.addRenderTarget(gBufferPassRTName, AccessType.WRITE, '_', LoadOp.CLEAR, StoreOp.DISCARD, emptyColor); + gBufferPass.addRenderTarget(gBufferPassNormal, AccessType.WRITE, '_', LoadOp.CLEAR, StoreOp.DISCARD, emptyColor); + gBufferPass.addRenderTarget(gBufferPassEmissive, AccessType.WRITE, '_', LoadOp.CLEAR, StoreOp.DISCARD, emptyColor); + gBufferPass.addDepthStencil(gBufferPassDSName, AccessType.WRITE, '_', '_', + LoadOp.CLEAR, StoreOp.DISCARD, camera.clearDepth, camera.clearStencil, camera.clearFlag); + gBufferPass + .addQueue(QueueHint.RENDER_OPAQUE, 'gbuffer-tiled') + .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.CUTOUT_OBJECT); + + // lighting subpass + const lightingPass = scenePass.addRenderSubpass('deferred-lighting-tiled'); + lightingPass.name = `CameraLightingPass${info.id}`; + lightingPass.setViewport(new Viewport(area.x, area.y, width, height)); + + lightingPass.addRenderTarget(gBufferPassRTName, AccessType.READ, 'albedoMap', LoadOp.DISCARD, StoreOp.DISCARD); + lightingPass.addRenderTarget(gBufferPassNormal, AccessType.READ, 'normalMap', LoadOp.DISCARD, StoreOp.DISCARD); + lightingPass.addRenderTarget(gBufferPassEmissive, AccessType.READ, 'emissiveMap', LoadOp.DISCARD, StoreOp.DISCARD); + lightingPass.addDepthStencil(gBufferPassDSName, AccessType.READ, 'depthStencil', '_', LoadOp.DISCARD, StoreOp.DISCARD); + + // cluster data + const clusterLightBufferName = `clusterLightBuffer${cameraID}`; + const clusterLightIndicesBufferName = `clusterLightIndicesBuffer${cameraID}`; + const clusterLightGridBufferName = `clusterLightGridBuffer${cameraID}`; + if (ppl.containsResource(clusterLightBufferName)) { + lightingPass.addStorageBuffer(clusterLightBufferName, AccessType.READ, 'b_ccLightsBuffer'); + lightingPass.addStorageBuffer(clusterLightIndicesBufferName, AccessType.READ, 'b_clusterLightIndicesBuffer'); + lightingPass.addStorageBuffer(clusterLightGridBufferName, AccessType.READ, 'b_clusterLightGridBuffer'); + } + + const deferredLightingPassRTName = `deferredLightingPassRTName${info.id}`; + lightingPass.addRenderTarget(deferredLightingPassRTName, AccessType.WRITE, '_', LoadOp.CLEAR, StoreOp.STORE, rtColor); + lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT, 'deferred-lighting-tiled').addCameraQuad( + camera, lightingInfo.deferredLightingMaterial, 1, + SceneFlags.VOLUMETRIC_LIGHTING, + ); + return { rtName: deferredLightingPassRTName }; +} + export function setupGBufferPass (ppl: BasicPipeline, info: CameraInfo) { const camera = info.camera; const area = getRenderArea(camera, camera.window.width, camera.window.height); @@ -397,7 +510,7 @@ export function setupGBufferPass (ppl: BasicPipeline, info: CameraInfo) { const gBufferPassEmissive = gBufferInfo.emissive; const gBufferPassDSName = gBufferInfo.ds; // gbuffer pass - const gBufferPass = ppl.addRenderPass(width, height, 'default'); + const gBufferPass = ppl.addRenderPass(width, height, 'gbuffer'); gBufferPass.name = `CameraGBufferPass${info.id}`; gBufferPass.setViewport(new Viewport(area.x, area.y, width, height)); const rtColor = new Color(0, 0, 0, 0); @@ -411,11 +524,11 @@ export function setupGBufferPass (ppl: BasicPipeline, info: CameraInfo) { } } gBufferPass.addRenderTarget(gBufferPassRTName, LoadOp.CLEAR, StoreOp.STORE, rtColor); - gBufferPass.addRenderTarget(gBufferPassNormal, LoadOp.CLEAR, StoreOp.STORE, new Color(0, 0, 0, 0)); gBufferPass.addRenderTarget(gBufferPassEmissive, LoadOp.CLEAR, StoreOp.STORE, new Color(0, 0, 0, 0)); + gBufferPass.addRenderTarget(gBufferPassNormal, LoadOp.CLEAR, StoreOp.STORE, new Color(0, 0, 0, 0)); gBufferPass.addDepthStencil(gBufferPassDSName, LoadOp.CLEAR, StoreOp.STORE, camera.clearDepth, camera.clearStencil, camera.clearFlag); gBufferPass - .addQueue(QueueHint.RENDER_OPAQUE) + .addQueue(QueueHint.RENDER_OPAQUE, 'gbuffer') .addSceneOfCamera(camera, new LightInfo(), SceneFlags.OPAQUE_OBJECT | SceneFlags.CUTOUT_OBJECT); return gBufferPass; } @@ -427,10 +540,8 @@ export function setupLightingRes (ppl: BasicPipeline, info: CameraInfo) { const width = area.width; const height = area.height; - const deferredLightingPassRTName = `deferredLightingPassRTName`; - const deferredLightingPassDS = `deferredLightingPassDS`; + const deferredLightingPassRTName = `deferredLightingPassRTName${info.id}`; ppl.addRenderTarget(deferredLightingPassRTName, Format.RGBA8, width, height, ResourceResidency.MANAGED); - ppl.addDepthStencil(deferredLightingPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } export function updateLightingRes (ppl: BasicPipeline, info: CameraInfo) { @@ -440,24 +551,23 @@ export function updateLightingRes (ppl: BasicPipeline, info: CameraInfo) { const width = area.width; const height = area.height; - const deferredLightingPassRTName = `deferredLightingPassRTName`; - const deferredLightingPassDS = `deferredLightingPassDS`; + const deferredLightingPassRTName = `deferredLightingPassRTName${info.id}`; ppl.updateRenderTarget(deferredLightingPassRTName, width, height); - ppl.updateDepthStencil(deferredLightingPassDS, width, height); } let lightingInfo: LightingInfo; -export function setupLightingPass (ppl: BasicPipeline, info: CameraInfo) { - setupShadowPass(ppl, info); +export function setupLightingPass (pipeline: BasicPipeline, info: CameraInfo, useCluster: boolean) { + setupShadowPass(pipeline, info); if (!lightingInfo) { - lightingInfo = new LightingInfo(); + lightingInfo = new LightingInfo(useCluster); } + const ppl = pipeline as Pipeline; const camera = info.camera; const area = getRenderArea(camera, camera.window.width, camera.window.height); const width = area.width; const height = area.height; + const cameraID = getCameraUniqueID(camera); - const deferredLightingPassRTName = `deferredLightingPassRTName`; - const deferredLightingPassDS = `deferredLightingPassDS`; + const deferredLightingPassRTName = `deferredLightingPassRTName${info.id}`; // lighting pass const lightingPass = ppl.addRenderPass(width, height, 'deferred-lighting'); lightingPass.name = `CameraLightingPass${info.id}`; @@ -473,11 +583,22 @@ export function setupLightingPass (ppl: BasicPipeline, info: CameraInfo) { } } if (ppl.containsResource(gBufferInfo.color)) { - lightingPass.addTexture(gBufferInfo.color, 'gbuffer_albedoMap'); - lightingPass.addTexture(gBufferInfo.normal, 'gbuffer_normalMap'); - lightingPass.addTexture(gBufferInfo.emissive, 'gbuffer_emissiveMap'); - lightingPass.addTexture(gBufferInfo.ds, 'depth_stencil'); + lightingPass.addTexture(gBufferInfo.color, 'albedoMap'); + lightingPass.addTexture(gBufferInfo.normal, 'normalMap'); + lightingPass.addTexture(gBufferInfo.emissive, 'emissiveMap'); + lightingPass.addTexture(gBufferInfo.ds, 'depthStencil'); + } + + // cluster data + const clusterLightBufferName = `clusterLightBuffer${cameraID}`; + const clusterLightIndicesBufferName = `clusterLightIndicesBuffer${cameraID}`; + const clusterLightGridBufferName = `clusterLightGridBuffer${cameraID}`; + if (ppl.containsResource(clusterLightBufferName)) { + lightingPass.addStorageBuffer(clusterLightBufferName, AccessType.READ, 'b_ccLightsBuffer'); + lightingPass.addStorageBuffer(clusterLightIndicesBufferName, AccessType.READ, 'b_clusterLightIndicesBuffer'); + lightingPass.addStorageBuffer(clusterLightGridBufferName, AccessType.READ, 'b_clusterLightGridBuffer'); } + const lightingClearColor = new Color(0, 0, 0, 0); if (camera.clearFlag & ClearFlagBit.COLOR) { lightingClearColor.x = camera.clearColor.x; @@ -492,7 +613,7 @@ export function setupLightingPass (ppl: BasicPipeline, info: CameraInfo) { ); // lightingPass.addQueue(QueueHint.RENDER_TRANSPARENT).addSceneOfCamera(camera, new LightInfo(), // SceneFlags.TRANSPARENT_OBJECT | SceneFlags.PLANAR_SHADOW | SceneFlags.GEOMETRY); - return { rtName: deferredLightingPassRTName, dsName: deferredLightingPassDS }; + return { rtName: deferredLightingPassRTName }; } export function setupPostprocessRes (ppl: BasicPipeline, info: CameraInfo) { @@ -504,7 +625,7 @@ export function setupPostprocessRes (ppl: BasicPipeline, info: CameraInfo) { const postprocessPassRTName = `postprocessPassRTName${cameraID}`; const postprocessPassDS = `postprocessPassDS${cameraID}`; ppl.addRenderWindow(postprocessPassRTName, Format.BGRA8, width, height, camera.window); - ppl.addDepthStencil(postprocessPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.EXTERNAL); + ppl.addDepthStencil(postprocessPassDS, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } export function updatePostprocessRes (ppl: BasicPipeline, info: CameraInfo) { @@ -549,8 +670,9 @@ export function setupPostprocessPass (ppl: BasicPipeline, postprocessPass.addDepthStencil(postprocessPassDS, getLoadOpOfClearFlag(camera.clearFlag, AttachmentType.DEPTH_STENCIL), StoreOp.STORE, camera.clearDepth, camera.clearStencil, camera.clearFlag); - postprocessPass.addQueue(QueueHint.NONE).addFullscreenQuad( - postInfo.postMaterial, 0, SceneFlags.NONE, + postprocessPass.addQueue(QueueHint.NONE).addCameraQuad( + camera, postInfo.postMaterial, 0, + SceneFlags.NONE, ); if (getProfilerCamera() === camera) { postprocessPass.showStatistics = true; @@ -568,7 +690,7 @@ export function setupUIRes (ppl: BasicPipeline, const dsUIAndProfilerPassRTName = `dsUIAndProfilerPassColor${info.id}`; const dsUIAndProfilerPassDSName = `dsUIAndProfilerPassDS${info.id}`; ppl.addRenderWindow(dsUIAndProfilerPassRTName, Format.BGRA8, width, height, camera.window); - ppl.addDepthStencil(dsUIAndProfilerPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.EXTERNAL); + ppl.addDepthStencil(dsUIAndProfilerPassDSName, Format.DEPTH_STENCIL, width, height, ResourceResidency.MANAGED); } export function updateUIRes (ppl: BasicPipeline, diff --git a/cocos/rendering/post-process/passes/forward-pass.ts b/cocos/rendering/post-process/passes/forward-pass.ts index a6def0cf7b7..b26b0758af8 100644 --- a/cocos/rendering/post-process/passes/forward-pass.ts +++ b/cocos/rendering/post-process/passes/forward-pass.ts @@ -71,7 +71,6 @@ export class ForwardPass extends BasePass { } } } - pass.addQueue(QueueHint.RENDER_OPAQUE) .addSceneOfCamera(camera, new LightInfo(), diff --git a/editor/assets/chunks/common/common-define.chunk b/editor/assets/chunks/common/common-define.chunk index 8308d4fa693..27fc46daadb 100644 --- a/editor/assets/chunks/common/common-define.chunk +++ b/editor/assets/chunks/common/common-define.chunk @@ -8,13 +8,13 @@ #define PI 3.14159265359 #define PI2 6.28318530718 #define PI4 12.5663706144 - + #define INV_QUATER_PI 1.27323954474 #define INV_HALF_PI 0.63661977237 #define INV_PI 0.31830988618 #define INV_PI2 0.15915494309 #define INV_PI4 0.07957747155 - + #define EPSILON 1e-6 #define EPSILON_LOWP 1e-4 #define LOG2 1.442695 @@ -46,7 +46,6 @@ vec4 saturate(vec4 value) { return clamp(value, vec4(0.0), vec4(1.0)); } #pragma define-meta CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT default(0) #pragma define-meta CC_PLATFORM_ANDROID_AND_WEBGL default(0) #pragma define-meta CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES default(0) -#pragma define-meta CC_ENABLE_CLUSTERED_LIGHT_CULLING default(0) // When sampling RTs, Y-flip is needed if the screen space sign Y is positive (pointing upwards) #pragma define CC_HANDLE_RT_SAMPLE_FLIP(uv) uv = cc_cameraPos.w > 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv diff --git a/editor/assets/chunks/common/math/coordinates.chunk b/editor/assets/chunks/common/math/coordinates.chunk index e78714070c9..08c05a227c9 100644 --- a/editor/assets/chunks/common/math/coordinates.chunk +++ b/editor/assets/chunks/common/math/coordinates.chunk @@ -2,6 +2,12 @@ // cc_cameraPos.w is flipNDCSign #pragma define CC_HANDLE_NDC_SAMPLE_FLIP(uv, flipNDCSign) uv = flipNDCSign == 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv +#ifdef CC_USE_METAL +#define CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(y) y = -y +#else +#define CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(y) +#endif + // return 0-1 vec2 GetScreenUV(vec4 clipPos, float flipNDCSign) diff --git a/editor/assets/chunks/legacy/shading-cluster-additive.chunk b/editor/assets/chunks/legacy/shading-cluster-additive.chunk index 3dc7965ca65..0bf35248e78 100644 --- a/editor/assets/chunks/legacy/shading-cluster-additive.chunk +++ b/editor/assets/chunks/legacy/shading-cluster-additive.chunk @@ -1,17 +1,20 @@ // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. -#pragma define CLUSTERS_X 16 -#pragma define CLUSTERS_Y 8 -#pragma define CLUSTERS_Z 24 +#pragma define CLUSTERS_X 16u +#pragma define CLUSTERS_Y 8u +#pragma define CLUSTERS_Z 24u #pragma define MAX_LIGHTS_PER_CLUSTER 100u -#pragma glBinding(4) -readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; }; +#pragma rate b_ccLightsBuffer pass +#pragma glBinding(0) +layout(std430) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; }; -#pragma glBinding(5) -readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; }; +#pragma rate b_clusterLightIndicesBuffer pass +#pragma glBinding(1) +layout(std430) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; }; -#pragma glBinding(6) -readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; }; +#pragma rate b_clusterLightGridBuffer pass +#pragma glBinding(2) +layout(std430) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; }; struct CCLight { @@ -19,6 +22,7 @@ struct CCLight vec4 cc_lightColor; vec4 cc_lightSizeRangeAngle; vec4 cc_lightDir; + vec4 cc_lightBoundingSizeVS; }; struct Cluster @@ -43,10 +47,11 @@ float screen2EyeDepth(float depth, float near, float far) CCLight getCCLight(uint i) { CCLight light; - light.cc_lightPos = b_ccLights[4u * i + 0u]; - light.cc_lightColor = b_ccLights[4u * i + 1u]; - light.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u]; - light.cc_lightDir = b_ccLights[4u * i + 3u]; + light.cc_lightPos = b_ccLights[5u * i + 0u]; + light.cc_lightColor = b_ccLights[5u * i + 1u]; + light.cc_lightSizeRangeAngle = b_ccLights[5u * i + 2u]; + light.cc_lightDir = b_ccLights[5u * i + 3u]; + light.cc_lightBoundingSizeVS = b_ccLights[5u * i + 4u]; return light; } @@ -79,7 +84,7 @@ uint getClusterIndex(vec4 fragCoord, vec4 worldPos) float clusterSizeX = ceil(cc_viewPort.z / float(CLUSTERS_X)); float clusterSizeY = ceil(cc_viewPort.w / float(CLUSTERS_Y)); uvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex); - uint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x; + uint cluster = (CLUSTERS_X * CLUSTERS_Y) * indices.z + CLUSTERS_X * indices.y + indices.x; return cluster; } @@ -133,7 +138,7 @@ vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) { float shadow = 1.0; #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP - if (IS_SPOT_LIGHT(light.cc_lightPos.w) && cc_lightSizeRangeAngle.w > 0.0) { + if (IS_SPOT_LIGHT(light.cc_lightPos.w) && light.cc_lightSizeRangeAngle.w > 0.0) { shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias); } #endif diff --git a/editor/assets/chunks/legacy/standard-surface-entry.chunk b/editor/assets/chunks/legacy/standard-surface-entry.chunk index a15b52fb858..5266ffb2129 100644 --- a/editor/assets/chunks/legacy/standard-surface-entry.chunk +++ b/editor/assets/chunks/legacy/standard-surface-entry.chunk @@ -45,15 +45,15 @@ #elif CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED \ #include \ \ - layout(location = 0) out vec4 fragColor0; \ - layout(location = 1) out vec4 fragColor1; \ - layout(location = 2) out vec4 fragColor2; \ + layout(location = 0) out vec4 albedoOut; \ + layout(location = 1) out vec4 emissiveOut; \ + layout(location = 2) out vec4 normalOut; \ \ void main () { \ StandardSurface s; surf(s); \ - fragColor0 = s.albedo; \ - fragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic); \ - fragColor2 = vec4(s.emissive, s.occlusion); \ + albedoOut = s.albedo; \ + normalOut = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic); \ + emissiveOut = vec4(s.emissive, s.occlusion); \ } \ \ #endif \ diff --git a/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk b/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk index 34828b08485..a9a6316003a 100644 --- a/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk +++ b/editor/assets/chunks/lighting-models/lighting-flow/common-flow.chunk @@ -1,5 +1,5 @@ #if (CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_FORWARD || CC_FORCE_FORWARD_SHADING) - #if CC_FORWARD_ADD && !CC_ENABLE_CLUSTERED_LIGHT_CULLING + #if CC_FORWARD_ADD void CCSurfacesLighting(inout LightingResult lightingResultAccumulated, in SurfacesMaterialData surfaceData, in vec2 shadowBias) { vec3 worldPos; @@ -30,7 +30,7 @@ vec3 lightDirWithLength = IS_RANGED_DIRECTIONAL_LIGHT(cc_lightPos[i].w) ? -normalize(cc_lightDir[i].xyz) : cc_lightPos[i].xyz - worldPos; CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, lightDirWithLength); CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData); - + vec3 diffuseLighting, specularLighting; CCSurfacesLightingCalculateDirect(diffuseLighting, specularLighting, lightingData, cc_lightColor[i]); @@ -57,7 +57,7 @@ #endif } #endif - + #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW) shadow = 1.0; @@ -134,11 +134,11 @@ { vec3 worldPos; HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, surfaceData.worldPos); - + LightingIntermediateData lightingData; CCSurfacesInitializeLightingIntermediateData(lightingData, surfaceData); CCSurfacesInitializeLightingResult(lightingResult, surfaceData); - + CCSurfacesLightingInitializeColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData); CCSurfacesLightingCalculateIntermediateData_PerLight(lightingData, surfaceData, -cc_mainLitDir.xyz); @@ -182,7 +182,7 @@ #if CC_SURFACES_USE_LIGHT_MAP && !CC_FORWARD_ADD float lightmapShadow, lightmapAO; GetLightMapColor(lightingResult.lightmapColor, lightmapShadow, lightmapAO, cc_lightingMap, FSInput_lightMapUV.xy, FSInput_lightMapUV.z, surfaceData.worldNormal); - + #if CC_SURFACES_USE_LIGHT_MAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION lightingResult.shadow *= lightmapShadow; #endif @@ -204,7 +204,7 @@ lightingResult.directDiffuse = lightingResult.directSpecular = vec3(0.0); #if !CC_DISABLE_DIRECTIONAL_LIGHT && !CC_FORWARD_ADD CCSurfacesLightingCalculateColorWithLighting(lightingResult.diffuseColorWithLighting, lightingResult.specularColorWithLighting, lightingResult.specularColorWithEnvLighting, surfaceData, lightingData); - + CCSurfacesLightingCalculateDirect(lightingResult.directDiffuse, lightingResult.directSpecular, lightingData, cc_mainLitColor); #endif @@ -220,7 +220,7 @@ CCSurfacesLightingCalculateDirectTransmitSpecular(lightingResult.directTransmitSpecular, lightingData, cc_mainLitColor); CCSurfacesLightingCalculateEnvironmentTransmitSpecular(lightingResult.environmentTransmitSpecular, lightingData, cc_ambientSky.w); #endif - + #if CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE LightingIntermediateData lightingDataTD; CCSurfacesGetLightingIntermediateDataTransmitDiffuse(lightingDataTD, lightingData, surfaceData); diff --git a/editor/assets/chunks/lighting-models/model-functions/toon.chunk b/editor/assets/chunks/lighting-models/model-functions/toon.chunk index 62558111318..cdea2dff79a 100644 --- a/editor/assets/chunks/lighting-models/model-functions/toon.chunk +++ b/editor/assets/chunks/lighting-models/model-functions/toon.chunk @@ -20,11 +20,11 @@ float CCSurfacesLightingCalculateAngleAttenuation(in LightingIntermediateData li void CCSurfacesLightingCalculateDirect(out vec3 lightingDiffuse, out vec3 lightingSpecular, in LightingIntermediateData lightingData, in vec4 lightSourceColorAndIntensity) { vec3 irradiance = lightSourceColorAndIntensity.rgb * lightSourceColorAndIntensity.w; - + lightingDiffuse = irradiance; // no energy conservation // punctual lighting is different from dir lighting -#if CC_FORWARD_ADD || CC_ENABLE_CLUSTERED_LIGHT_CULLING +#if CC_FORWARD_ADD float NL = 0.5 * lightingData.NoL + 0.5; lightingDiffuse *= NL; #endif diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/deferred-fs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/deferred-fs.chunk index 1bc8766e39d..4ce3131d2e6 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/deferred-fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/deferred-fs.chunk @@ -1,15 +1,16 @@ - layout(location = 0) out vec4 fragColor0; - layout(location = 1) out vec4 fragColor1; - layout(location = 2) out vec4 fragColor2; + layout(location = 0) out vec4 albedoOut; + layout(location = 1) out vec4 emissiveOut; + layout(location = 2) out vec4 normalOut; void main () { // Surface SurfacesMaterialData surfaceData; CCSurfacesFragmentGetMaterialData(surfaceData); - fragColor0 = CCSurfacesDeferredOutput0(surfaceData); - fragColor1 = CCSurfacesDeferredOutput1(surfaceData); - fragColor2 = CCSurfacesDeferredOutput2(surfaceData); + // location of subpass output should be ordered by name. + albedoOut = CCSurfacesDeferredOutputBaseColor(surfaceData); + normalOut = CCSurfacesDeferredOutputNormalMR(surfaceData); + emissiveOut = CCSurfacesDeferredOutputEmissiveAO(surfaceData); // Debug view #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_SINGLE && CC_SURFACES_ENABLE_DEBUG_VIEW @@ -17,7 +18,7 @@ CCSurfacesDebugViewMeshData(debugColor); CCSurfacesDebugViewSurfaceData(debugColor, surfaceData); if (IS_DEBUG_VIEW_ENABLE_WITH_CAMERA) { - fragColor0 = debugColor; + albedoOut = debugColor; } #endif } diff --git a/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk b/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk index df4a67ce351..ce3c9a81b59 100644 --- a/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/standard-fs.chunk @@ -236,15 +236,15 @@ void CCSurfacesAccumulateLightingResult(inout LightingResult lightingResultAccum #if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED - vec4 CCSurfacesDeferredOutput0(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputBaseColor(in SurfacesMaterialData surfaceData) { return surfaceData.baseColor; } - vec4 CCSurfacesDeferredOutput1(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputNormalMR(in SurfacesMaterialData surfaceData) { return vec4(float32x3_to_oct(surfaceData.worldNormal), surfaceData.roughness, surfaceData.metallic); } - vec4 CCSurfacesDeferredOutput2(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputEmissiveAO(in SurfacesMaterialData surfaceData) { return vec4(surfaceData.emissive, surfaceData.ao); } diff --git a/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk b/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk index d530b9022c5..5afc2f508e4 100644 --- a/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/toon-fs.chunk @@ -105,15 +105,15 @@ void CCSurfacesAccumulateLightingResult(inout LightingResult lightingResultAccum // Lighting #if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED - vec4 CCSurfacesDeferredOutput0(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputBaseColor(in SurfacesMaterialData surfaceData) { return surfaceData.baseColor; } - vec4 CCSurfacesDeferredOutput1(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputNormalMR(in SurfacesMaterialData surfaceData) { return vec4(float32x3_to_oct(surfaceData.worldNormal), 0.5, 0.0); } - vec4 CCSurfacesDeferredOutput2(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputEmissiveAO(in SurfacesMaterialData surfaceData) { return vec4(surfaceData.emissive, 1.0); } diff --git a/editor/assets/chunks/surfaces/module-functions/unlit-fs.chunk b/editor/assets/chunks/surfaces/module-functions/unlit-fs.chunk index 720a14100cb..edc14d1b03f 100644 --- a/editor/assets/chunks/surfaces/module-functions/unlit-fs.chunk +++ b/editor/assets/chunks/surfaces/module-functions/unlit-fs.chunk @@ -39,15 +39,15 @@ void CCSurfacesLightingCalculateColorWithLighting(inout vec3 diffuseColorWithLig #if CC_PIPELINE_TYPE == CC_PIPELINE_TYPE_DEFERRED - vec4 CCSurfacesDeferredOutput0(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputBaseColor(in SurfacesMaterialData surfaceData) { return surfaceData.baseColor; } - vec4 CCSurfacesDeferredOutput1(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputNormalMR(in SurfacesMaterialData surfaceData) { return vec4(float32x3_to_oct(vec3(0.0, 1.0, 0.0)), 0.0, 0.0); } - vec4 CCSurfacesDeferredOutput2(in SurfacesMaterialData surfaceData) + vec4 CCSurfacesDeferredOutputEmissiveAO(in SurfacesMaterialData surfaceData) { return vec4(0.0, 0.0, 0.0, 1.0); } diff --git a/editor/assets/effects/advanced/eye.effect b/editor/assets/effects/advanced/eye.effect index 55a7206fc1e..d2ff3f7dca0 100644 --- a/editor/assets/effects/advanced/eye.effect +++ b/editor/assets/effects/advanced/eye.effect @@ -65,15 +65,20 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -82,6 +87,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward-transparent + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -131,7 +144,7 @@ CCProgram surface-fragment %{ in vec4 v_planeT; #if USE_IRIS_REFRACTION uniform sampler2D irisNormalMap; - #endif + #endif uniform sampler2D irisHeightMap; uniform sampler2D irisHeightMapAlpha; uniform sampler2D irisColorMaskMap; @@ -178,7 +191,7 @@ CCProgram surface-fragment %{ return vec2(dot(refract, planeT), dot(refract, -planeB)); } - + // definition of SurfacesMaterialData structure with corresponding shading-model #include @@ -189,7 +202,7 @@ CCProgram surface-fragment %{ vec3 worldPos; HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, surfaceData.worldPos); - float irisHeightScale = irisParams.x; + float irisHeightScale = irisParams.x; float IrisUVRadius = irisParams.z * 2.0; // default is 0.5 float PupilScale = irisParams.w; float VeinsPower = irisParams.y; @@ -252,7 +265,7 @@ CCProgram surface-fragment %{ #if USE_IRIS_REFRACTION vec3 worldPos; HIGHP_VALUE_FROM_STRUCT_DEFINED(worldPos, surfaceData.worldPos); - + vec3 L = lightingData.L; vec3 viewDir = normalize(cc_cameraPos.xyz - worldPos); @@ -261,7 +274,7 @@ CCProgram surface-fragment %{ CCSurfacesLightingGetIntermediateData_PerLight(lightingDataRefract, newL); if (surfaceData.emissive.x > 0.0) { result.directSpecular = CalculateDirectSpecular(lightingDataRefract, miscData.lightColorAndIntensity); - + #if !CC_FORWARD_ADD lightingDataRefract.V = -CalculateRefractDirection(surfaceData.worldNormal, viewDir, dot(surfaceData.worldNormal, viewDir), CONREAL_IOR); result.environmentSpecular = CalculateEnvironmentSpecular(lightingDataRefract, cc_ambientSky.w); diff --git a/editor/assets/effects/advanced/leaf.effect b/editor/assets/effects/advanced/leaf.effect index f7b8c6ae2b0..184d7476445 100644 --- a/editor/assets/effects/advanced/leaf.effect +++ b/editor/assets/effects/advanced/leaf.effect @@ -24,9 +24,9 @@ CCEffect %{ extinction: { value: 0.0, target: scatterParams.y, editor: { displayName: Scatter Extinction, slide: true, range: [0, 3.0], step: 0.001 } } thickness: { value: 1.0, target: scatterParams.z, editor: { displayName: Thickness Scaling, slide: true, range: [0, 3.0], step: 0.001 } } scatterColor: { value: [0.5, 0.75, 0.2, 1.0], linear: true, editor: { displayName: Scatter Color, type: color, tooltip: 'The color of scattered lighting' } } - rasterizerState: + rasterizerState: &r1 cullMode: None - depthStencilState: + depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true @@ -62,15 +62,23 @@ CCEffect %{ albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 + depthStencilState: *d1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &dt depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -79,6 +87,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward-transparent + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *dt + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -104,7 +120,7 @@ CCProgram macro-remapping %{ #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE #define CC_SURFACES_USE_VERTEX_COLOR USE_VERTEX_COLOR - + #define CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE 1 #define CC_SURFACES_TRANSFER_CLIP_POS 1 @@ -180,7 +196,7 @@ CCProgram surface-fragment %{ { return vec3(0.0); } - + #define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_OUT_SCATTERING_COLOR vec3 SurfacesFragmentModifyTransmitOutScatteringColor() { diff --git a/editor/assets/effects/advanced/simple-skin.effect b/editor/assets/effects/advanced/simple-skin.effect index df8ffa22bf1..f630258f895 100644 --- a/editor/assets/effects/advanced/simple-skin.effect +++ b/editor/assets/effects/advanced/simple-skin.effect @@ -31,9 +31,9 @@ CCEffect %{ transmitColor: { value: [1.0, 0.2, 0.1, 1.0], linear: true, editor: { parent: USE_BACK_LIT, displayName: Transmit Scatter Color, type: color, tooltip: 'The color of scattered lighting, red for human skin' } } dualLobeRoughness: { value: 0.5, target: dualLobeParams.x, editor: { parent: USE_DUAL_LOBE_SPECULAR, range: [0, 1.0] } } dualLobeIntensity: { value: 0.02, target: dualLobeParams.w, editor: { parent: USE_DUAL_LOBE_SPECULAR, slide: true, range: [0, 0.1], step: 0.001 } } - rasterizerState: + rasterizerState: &r1 cullMode: None - depthStencilState: + depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true @@ -69,15 +69,24 @@ CCEffect %{ albedoScale: { value: [1.0, 1.0, 1.0], target: albedoScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: albedoScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } + + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 + depthStencilState: *d1 + - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &dt depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -86,6 +95,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward-transparent + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *dt + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -113,7 +130,7 @@ CCProgram macro-remapping %{ #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE #define CC_SURFACES_USE_VERTEX_COLOR USE_VERTEX_COLOR - + #define CC_SURFACES_LIGHTING_DUAL_LOBE_SPECULAR USE_DUAL_LOBE_SPECULAR #define CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE USE_BACK_LIT #define CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT USE_BACK_LIT @@ -184,7 +201,7 @@ CCProgram surface-fragment %{ { return vec3(0.0);//1.0, 0.2, 0.05); } - + #define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_OUT_SCATTERING_COLOR vec3 SurfacesFragmentModifyTransmitOutScatteringColor() { @@ -226,7 +243,7 @@ CCProgram surface-fragment %{ pbr.w *= cavity; return pbr; } - + #include #include }% diff --git a/editor/assets/effects/advanced/skin.effect b/editor/assets/effects/advanced/skin.effect index 706c51b2726..4b049f0d2fb 100644 --- a/editor/assets/effects/advanced/skin.effect +++ b/editor/assets/effects/advanced/skin.effect @@ -29,9 +29,9 @@ CCEffect %{ transmitColor: { value: [1.0, 0.2, 0.1, 1.0], linear: true, editor: { parent: USE_BACK_LIT, displayName: Transmit Scatter Color, type: color, tooltip: 'The color of scattered lighting, red for human skin' } } dualLobeRoughness: { value: 0.5, target: dualLobeParams.x, editor: { parent: USE_DUAL_LOBE_SPECULAR, range: [0, 1.0] } } dualLobeIntensity: { value: 0.02, target: dualLobeParams.w, editor: { parent: USE_DUAL_LOBE_SPECULAR, slide: true, range: [0, 0.1], step: 0.001 } } - rasterizerState: + rasterizerState: &r1 cullMode: None - depthStencilState: + depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true @@ -109,6 +109,14 @@ CCEffect %{ blendDst: one blendSrcAlpha: zero blendDstAlpha: one + + - vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + embeddedMacros: { CC_SURFACES_LIGHTING_DISABLE_DIFFUSE: false, CC_SURFACES_LIGHTING_DISABLE_SPECULAR: true } + rasterizerState: *r1 + depthStencilState: *d1 }% CCProgram shared-ubos %{ @@ -135,7 +143,7 @@ CCProgram macro-remapping %{ #define CC_SURFACES_USE_SECOND_UV HAS_SECOND_UV #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE #define CC_SURFACES_USE_VERTEX_COLOR USE_VERTEX_COLOR - + #define CC_SURFACES_LIGHTING_DUAL_LOBE_SPECULAR USE_DUAL_LOBE_SPECULAR #define CC_SURFACES_LIGHTING_TRANSMIT_DIFFUSE USE_BACK_LIT #define CC_SURFACES_LIGHTING_USE_SHADOWMAP_TRANSMIT USE_BACK_LIT @@ -206,7 +214,7 @@ CCProgram surface-fragment %{ { return vec3(0.0);//1.0, 0.2, 0.05); } - + #define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_OUT_SCATTERING_COLOR vec3 SurfacesFragmentModifyTransmitOutScatteringColor() { diff --git a/editor/assets/effects/advanced/sky.effect b/editor/assets/effects/advanced/sky.effect index 1a75ea68063..d8c9f59d29d 100644 --- a/editor/assets/effects/advanced/sky.effect +++ b/editor/assets/effects/advanced/sky.effect @@ -9,11 +9,19 @@ CCEffect %{ properties: &props environmentMap: { value: grey } priority : max - 10 - rasterizerState : + rasterizerState : &r1 cullMode : none - depthStencilState : + depthStencilState : &d1 depthTest: true depthWrite : false + + - vert: sky-vs + frag: sky-fs + phase: deferred-forward + propertyIndex: 0 + priority: max - 10 + rasterizerState: *r1 + depthStencilState: *d1 }% diff --git a/editor/assets/effects/advanced/water.effect b/editor/assets/effects/advanced/water.effect index 604659e5aaf..5cb52d1c38a 100644 --- a/editor/assets/effects/advanced/water.effect +++ b/editor/assets/effects/advanced/water.effect @@ -21,7 +21,7 @@ CCEffect %{ detailedIntensity: { value: 0.5, target: waterParam.w, editor: { parent: USE_NORMAL_MAP, slide: true, range: [0, 1.0], step: 0.001 } } waterInScatterColor: { value: [0.07, 0.13, 0.087, 1.0], target: waterColor, linear: true, editor: { parent: USE_WATER_SCATTERING, type: color } } waterScatterCoef: { value: 3.0, target: waterColor.w, editor: { parent: USE_WATER_SCATTERING, range: [0, 10.0], tooltip: 'The higher the value, the more turbid or deeper the water is.' } } - rasterizerState: + rasterizerState: &r1 cullMode: none - &forward-add vert: standard-vs @@ -57,15 +57,21 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -74,6 +80,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward-transparent + vert: standard-vs + frag: standard-fs + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + phase: deferred-forward + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -94,7 +108,7 @@ CCProgram macro-remapping %{ #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE #define CC_SURFACES_LIGHTING_USE_FRESNEL 1 #define CC_SURFACES_LIGHTING_TRANSMIT_SPECULAR 1 - + // depend on UI macros #if USE_NORMAL_MAP #define CC_SURFACES_USE_TANGENT_SPACE 1 @@ -121,7 +135,7 @@ CCProgram surface-fragment %{ vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 baseColor = albedo; - + #if USE_VERTEX_COLOR baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear baseColor.a *= FSInput_vertexColor.a; diff --git a/editor/assets/effects/builtin-reflection-probe-preview.effect b/editor/assets/effects/builtin-reflection-probe-preview.effect index a47e6051aca..d22c0618bb0 100644 --- a/editor/assets/effects/builtin-reflection-probe-preview.effect +++ b/editor/assets/effects/builtin-reflection-probe-preview.effect @@ -9,6 +9,11 @@ CCEffect %{ migrations: &migs properties: mainColor: { formerlySerializedAs: color } + - vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + propertyIndex: 0 + migrations: *migs - name: transparent passes: - vert: unlit-vs:vert @@ -16,7 +21,7 @@ CCEffect %{ depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -24,13 +29,20 @@ CCEffect %{ blendDstAlpha: one_minus_src_alpha properties: *props migrations: *migs + - vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 + migrations: *migs - name: add passes: - vert: unlit-vs:vert frag: unlit-fs:frag rasterizerState: &r1 { cullMode: none } depthStencilState: *d1 - blendState: + blendState: &b2 targets: - blend: true blendSrc: src_alpha @@ -39,13 +51,20 @@ CCEffect %{ blendDstAlpha: one properties: *props migrations: *migs + - vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 + migrations: *migs - name: alpha-blend passes: - vert: unlit-vs:vert frag: unlit-fs:frag rasterizerState: *r1 depthStencilState: *d1 - blendState: + blendState: &b3 targets: - blend: true blendSrc: src_alpha @@ -54,6 +73,13 @@ CCEffect %{ blendDstAlpha: one_minus_src_alpha properties: *props migrations: *migs + - vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + depthStencilState: *d1 + blendState: *b3 + propertyIndex: 0 + migrations: *migs }% CCProgram unlit-vs %{ @@ -70,7 +96,7 @@ CCProgram unlit-vs %{ out mediump vec3 v_position; out mediump vec3 v_normal; - + vec4 vert () { vec4 position; CCVertInput(position); @@ -89,7 +115,7 @@ CCProgram unlit-vs %{ v_shadowBiasAndProbeId.zw = cc_localShadowBias.zw; #endif #endif - + return cc_matProj * (cc_matView * matWorld) * position; } }% diff --git a/editor/assets/effects/builtin-standard.effect b/editor/assets/effects/builtin-standard.effect index 9bca925d419..396c0e4ce83 100644 --- a/editor/assets/effects/builtin-standard.effect +++ b/editor/assets/effects/builtin-standard.effect @@ -84,15 +84,22 @@ CCEffect %{ blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha + - &deferred + vert: standard-vs + frag: standard-fs + pass: gbuffer + phase: gbuffer + embeddedMacros: { CC_PIPELINE_TYPE: 1 } + propertyIndex: 0 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -102,6 +109,14 @@ CCEffect %{ - *forward-add - *shadow-caster - *planar-shadow + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + propertyIndex: 0 + depthStencilState: *d1 + blendState: *b1 }% CCProgram shared-ubos %{ @@ -153,7 +168,7 @@ CCProgram surface-vertex %{ worldPos.y += cos(cc_time.x * worldPos.z); return worldPos; } - + #define CC_SURFACES_VERTEX_MODIFY_WORLD_NORMAL vec3 SurfacesVertexModifyWorldNormal(in SurfacesStandardVertexIntermediate In) { @@ -165,14 +180,14 @@ CCProgram surface-vertex %{ #endif return normalize(worldNormal); } - + // see for more overrided functions #define CC_SURFACES_VERTEX_MODIFY_SHARED_DATA void SurfacesVertexModifySharedData(inout SurfacesStandardVertexIntermediate In) { } */ - + #define CC_SURFACES_VERTEX_MODIFY_UV void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) { @@ -222,7 +237,7 @@ CCProgram surface-fragment %{ vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 baseColor = albedo; - + #if USE_VERTEX_COLOR baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear baseColor.a *= FSInput_vertexColor.a; @@ -253,7 +268,7 @@ CCProgram surface-fragment %{ #if USE_ALBEDO_MAP alpha = texture(albedoMap, ALBEDO_UV).ALPHA_TEST_CHANNEL; #endif - + if (alpha < albedoScaleAndCutoff.w) discard; #endif } diff --git a/editor/assets/effects/builtin-terrain.effect b/editor/assets/effects/builtin-terrain.effect index ac5d592ee6d..82df4878104 100644 --- a/editor/assets/effects/builtin-terrain.effect +++ b/editor/assets/effects/builtin-terrain.effect @@ -47,6 +47,10 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - vert: terrain-vs + frag: terrain-fs + phase: deferred-forwar + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -62,10 +66,10 @@ CCProgram macro-remapping %{ #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMALMAP }% -CCProgram surface-vertex %{ +CCProgram surface-vertex %{ #define CC_SURFACES_VERTEX_MODIFY_WORLD_POS vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In) - { + { vec3 worldPos; worldPos.x = cc_matWorld[3][0] + In.position.x; worldPos.y = cc_matWorld[3][1] + In.position.y; diff --git a/editor/assets/effects/builtin-toon.effect b/editor/assets/effects/builtin-toon.effect index 2d60ea3cbcd..6fc7ca06a63 100644 --- a/editor/assets/effects/builtin-toon.effect +++ b/editor/assets/effects/builtin-toon.effect @@ -6,9 +6,9 @@ CCEffect %{ - switch: USE_OUTLINE_PASS vert: silhouette-edge-vs frag: silhouette-edge-fs - rasterizerState: + rasterizerState: &r1 cullMode: front - depthStencilState: + depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true @@ -100,6 +100,17 @@ CCEffect %{ blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha + - switch: USE_OUTLINE_PASS + vert: silhouette-edge-vs + frag: silhouette-edge-fs + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + propertyIndex: 0 + - vert: toon-vs + frag: toon-fs + phase: deferred-forward + propertyIndex: 1 }% CCProgram shared-ubos %{ @@ -203,7 +214,7 @@ CCProgram surface-fragment %{ #if USE_BASE_COLOR_MAP alpha = texture(baseColorMap, FSInput_texcoord).ALPHA_TEST_CHANNEL; #endif - + if (alpha < colorScaleAndCutoff.w) discard; #endif } @@ -241,7 +252,7 @@ CCProgram surface-fragment %{ { return miscParams.x; } - + #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SPECULAR vec4 SurfacesFragmentModifyToonSpecular() { diff --git a/editor/assets/effects/builtin-unlit.effect b/editor/assets/effects/builtin-unlit.effect index 05c523d44dc..66dd4e82a30 100644 --- a/editor/assets/effects/builtin-unlit.effect +++ b/editor/assets/effects/builtin-unlit.effect @@ -35,6 +35,11 @@ CCEffect %{ blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha + - &deferred-forward + vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + propertyIndex: 0 - name: transparent passes: - vert: unlit-vs:vert @@ -42,7 +47,7 @@ CCEffect %{ depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -51,13 +56,21 @@ CCEffect %{ properties: *props migrations: *migs - *planar-shadow + - &deferred-forward-transparent + vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + propertyIndex: 0 + migrations: *migs + depthStencilState: *d1 + blendState: *b1 - name: add passes: - vert: unlit-vs:vert frag: unlit-fs:frag rasterizerState: &r1 { cullMode: none } depthStencilState: *d1 - blendState: + blendState: &b2 targets: - blend: true blendSrc: src_alpha @@ -66,13 +79,22 @@ CCEffect %{ blendDstAlpha: one properties: *props migrations: *migs + - &deferred-forward-add + vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 + migrations: *migs - name: alpha-blend passes: - vert: unlit-vs:vert frag: unlit-fs:frag rasterizerState: *r1 depthStencilState: *d1 - blendState: + blendState: &b3 targets: - blend: true blendSrc: src_alpha @@ -81,6 +103,15 @@ CCEffect %{ blendDstAlpha: one_minus_src_alpha properties: *props migrations: *migs + - &deferred-forward-alpha-blend + vert: unlit-vs:vert + frag: unlit-fs:frag + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b3 + propertyIndex: 0 + migrations: *migs }% CCProgram unlit-vs %{ diff --git a/editor/assets/effects/legacy/standard.effect b/editor/assets/effects/legacy/standard.effect index 95218dfb674..27a0f682fad 100644 --- a/editor/assets/effects/legacy/standard.effect +++ b/editor/assets/effects/legacy/standard.effect @@ -74,15 +74,22 @@ CCEffect %{ blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha + - &deferred + vert: standard-vs + frag: standard-fs + pass: gbuffer + phase: gbuffer + embeddedMacros: { CC_PIPELINE_TYPE: 1 } + propertyIndex: 0 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -92,6 +99,14 @@ CCEffect %{ - *forward-add - *shadow-caster - *planar-shadow + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + propertyIndex: 0 + depthStencilState: *d1 + blendState: *b1 }% CCProgram shared-ubos %{ @@ -301,7 +316,7 @@ CCProgram standard-fs %{ #endif #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND || CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_BLEND_AND_SKYBOX - s.reflectionProbeBlendId = v_shadowBiasAndProbeId.w; + s.reflectionProbeBlendId = v_shadowBiasAndProbeId.w; #if USE_INSTANCING s.reflectionProbeBlendFactor = v_reflectionProbeData.x; #else diff --git a/editor/assets/effects/legacy/terrain.effect b/editor/assets/effects/legacy/terrain.effect index 957d01b6fa1..45b652402b8 100644 --- a/editor/assets/effects/legacy/terrain.effect +++ b/editor/assets/effects/legacy/terrain.effect @@ -41,6 +41,10 @@ CCEffect %{ propertyIndex: 0 rasterizerState: cullMode: back + - vert: terrain-vs + frag: terrain-fs + phase: deferred-forward + propertyIndex: 0 }% CCProgram terrain-vs %{ @@ -309,7 +313,7 @@ CCProgram shadow-caster-fs %{ highp float clipDepth = v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5; //todo: do not support linear mode spot shadow - + #if CC_SHADOWMAP_FORMAT == SHADOWMAP_FORMAT_RGBA8 return packDepthToRGBA(clipDepth); #else diff --git a/editor/assets/effects/legacy/toon.effect b/editor/assets/effects/legacy/toon.effect index 1358a3d124e..8b17d1f90bc 100644 --- a/editor/assets/effects/legacy/toon.effect +++ b/editor/assets/effects/legacy/toon.effect @@ -6,9 +6,9 @@ CCEffect %{ - switch: USE_OUTLINE_PASS vert: legacy/main-functions/outline-vs:vert frag: legacy/main-functions/outline-fs:frag - rasterizerState: + rasterizerState: &r1 cullMode: front - depthStencilState: + depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true @@ -100,6 +100,17 @@ CCEffect %{ blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha + - switch: USE_OUTLINE_PASS + vert: legacy/main-functions/outline-vs:vert + frag: legacy/main-functions/outline-fs:frag + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + propertyIndex: 0 + - vert: toon-vs:vert + frag: toon-fs:frag + phase: deferred-forward + propertyIndex: 1 }% CCProgram shared-ubos %{ @@ -314,7 +325,7 @@ CCProgram shadow-caster-fs %{ #include #include #include - + in vec2 v_uv; in vec4 v_worldPos; in highp vec2 v_clip_depth; diff --git a/editor/assets/effects/particles/builtin-billboard.effect b/editor/assets/effects/particles/builtin-billboard.effect index ac98142cd9f..323c4bb0f38 100644 --- a/editor/assets/effects/particles/builtin-billboard.effect +++ b/editor/assets/effects/particles/builtin-billboard.effect @@ -32,6 +32,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p2 + - vert: vert:vs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: alpha-blend passes: - vert: vert:vs_main @@ -40,6 +47,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: vert:vs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: add-multiply passes: - vert: vert:vs_main @@ -48,6 +62,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: vert:vs_main + frag: tinted-fs:multiply + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: add-smooth passes: - vert: vert:vs_main @@ -56,6 +77,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: vert:vs_main + frag: no-tint-fs:addSmooth + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: premultiply-blend passes: - vert: vert:vs_main @@ -64,6 +92,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: vert:vs_main + frag: no-tint-fs:premultiplied + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 }% // TODO: soft particle diff --git a/editor/assets/effects/particles/builtin-particle-gpu.effect b/editor/assets/effects/particles/builtin-particle-gpu.effect index 7aaa5a3b8c5..17757a2c442 100644 --- a/editor/assets/effects/particles/builtin-particle-gpu.effect +++ b/editor/assets/effects/particles/builtin-particle-gpu.effect @@ -40,6 +40,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p2 + - vert: builtin/internal/particle-vs-gpu:gpvs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: alpha-blend passes: - vert: builtin/internal/particle-vs-gpu:gpvs_main @@ -48,6 +55,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: builtin/internal/particle-vs-gpu:gpvs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: add-multiply passes: - vert: builtin/internal/particle-vs-gpu:gpvs_main @@ -56,6 +70,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b3 properties: *p2 + - vert: builtin/internal/particle-vs-gpu:gpvs_main + frag: tinted-fs:multiply + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b3 + propertyIndex: 0 - name: add-smooth passes: - vert: builtin/internal/particle-vs-gpu:gpvs_main @@ -64,6 +85,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p1 + - vert: builtin/internal/particle-vs-gpu:gpvs_main + frag: no-tint-fs:addSmooth + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: premultiply-blend passes: - vert: builtin/internal/particle-vs-gpu:gpvs_main @@ -72,6 +100,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: builtin/internal/particle-vs-gpu:gpvs_main + frag: no-tint-fs:premultiplied + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 }% // TODO: soft particle diff --git a/editor/assets/effects/particles/builtin-particle-trail.effect b/editor/assets/effects/particles/builtin-particle-trail.effect index 37afc3ce1a5..3fdaac2fe6f 100644 --- a/editor/assets/effects/particles/builtin-particle-trail.effect +++ b/editor/assets/effects/particles/builtin-particle-trail.effect @@ -33,6 +33,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p2 + - vert: builtin/internal/particle-trail:vs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: alpha-blend passes: - vert: builtin/internal/particle-trail:vs_main @@ -41,6 +48,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: builtin/internal/particle-trail:vs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: add-multiply passes: - vert: builtin/internal/particle-trail:vs_main @@ -49,6 +63,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: builtin/internal/particle-trail:vs_main + frag: tinted-fs:multiply + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: add-smooth passes: - vert: builtin/internal/particle-trail:vs_main @@ -57,6 +78,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: builtin/internal/particle-trail:vs_main + frag: no-tint-fs:addSmooth + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: premultiply-blend passes: - vert: builtin/internal/particle-trail:vs_main @@ -65,6 +93,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: builtin/internal/particle-trail:vs_main + frag: no-tint-fs:premultiplied + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 }% // TODO: soft particle diff --git a/editor/assets/effects/particles/builtin-particle-xr-trail.effect b/editor/assets/effects/particles/builtin-particle-xr-trail.effect index 4472d2e21f1..e4abd293ea3 100644 --- a/editor/assets/effects/particles/builtin-particle-xr-trail.effect +++ b/editor/assets/effects/particles/builtin-particle-xr-trail.effect @@ -26,6 +26,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p2 + - vert: builtin/internal/particle-trail:vs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% // TODO: soft particle diff --git a/editor/assets/effects/particles/builtin-particle.effect b/editor/assets/effects/particles/builtin-particle.effect index d7838b29e54..057016f1891 100644 --- a/editor/assets/effects/particles/builtin-particle.effect +++ b/editor/assets/effects/particles/builtin-particle.effect @@ -40,6 +40,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p2 + - vert: builtin/internal/particle-vs-legacy:lpvs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: alpha-blend passes: - vert: builtin/internal/particle-vs-legacy:lpvs_main @@ -48,6 +55,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p2 + - vert: builtin/internal/particle-vs-legacy:lpvs_main + frag: tinted-fs:add + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 - name: add-multiply passes: - vert: builtin/internal/particle-vs-legacy:lpvs_main @@ -56,6 +70,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b3 properties: *p2 + - vert: builtin/internal/particle-vs-legacy:lpvs_main + frag: tinted-fs:multiply + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b3 + propertyIndex: 0 - name: add-smooth passes: - vert: builtin/internal/particle-vs-legacy:lpvs_main @@ -64,6 +85,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b1 properties: *p1 + - vert: builtin/internal/particle-vs-legacy:lpvs_main + frag: no-tint-fs:addSmooth + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 - name: premultiply-blend passes: - vert: builtin/internal/particle-vs-legacy:lpvs_main @@ -72,6 +100,13 @@ CCEffect %{ depthStencilState: *d1 blendState: *b2 properties: *p1 + - vert: builtin/internal/particle-vs-legacy:lpvs_main + frag: no-tint-fs:premultiplied + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 + blendState: *b2 + propertyIndex: 0 }% // TODO: soft particle diff --git a/editor/assets/effects/pipeline/cluster-build.effect b/editor/assets/effects/pipeline/cluster-build.effect index 505e1ccac73..fd4f229455f 100644 --- a/editor/assets/effects/pipeline/cluster-build.effect +++ b/editor/assets/effects/pipeline/cluster-build.effect @@ -10,10 +10,14 @@ CCEffect %{ CCProgram cluster-main %{ + #include + precision highp float; - #define LOCAL_SIZE_Z 1 + #define LOCAL_SIZE_X 16u + #define LOCAL_SIZE_Y 8u + #define LOCAL_SIZE_Z 1u - layout (local_size_x = 16, local_size_y = 8, local_size_z = LOCAL_SIZE_Z) in; + layout (local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in; #pragma rate CCConst pass layout(std140) uniform CCConst { @@ -28,9 +32,12 @@ CCProgram cluster-main %{ vec4 screen2Eye(vec4 coord) { vec3 ndc = vec3( - 2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.x - 1.0, - 2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.y - 1.0, + 2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0, + 2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0, 2.0 * coord.z - 1.0); + + CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(ndc.y); + vec4 eye = ((cc_matProjInv) * (vec4(ndc, 1.0))); eye = eye / eye.w; return eye; @@ -42,8 +49,8 @@ CCProgram cluster-main %{ gl_GlobalInvocationID.y * gl_WorkGroupSize.x + gl_GlobalInvocationID.x; - float clusterSizeX = ceil(cc_viewPort.x / cc_workGroup.x); - float clusterSizeY = ceil(cc_viewPort.y / cc_workGroup.y); + float clusterSizeX = ceil(cc_viewPort.z / cc_workGroup.x); + float clusterSizeY = ceil(cc_viewPort.w / cc_workGroup.y); vec4 minScreen = vec4(vec2(gl_GlobalInvocationID.xy) * vec2(clusterSizeX, clusterSizeY), 1.0, 1.0); vec4 maxScreen = vec4(vec2(gl_GlobalInvocationID.xy + uvec2(1, 1)) * vec2(clusterSizeX, clusterSizeY), 1.0, 1.0); vec3 minEye = screen2Eye(minScreen).xyz; diff --git a/editor/assets/effects/pipeline/cluster-culling.effect b/editor/assets/effects/pipeline/cluster-culling.effect index e9f4fff53e7..9c418b01383 100644 --- a/editor/assets/effects/pipeline/cluster-culling.effect +++ b/editor/assets/effects/pipeline/cluster-culling.effect @@ -11,7 +11,10 @@ CCEffect %{ CCProgram cluster-main %{ precision highp float; - #define LOCAL_SIZE_Z 1 + #define LOCAL_SIZE_X 16u + #define LOCAL_SIZE_Y 8u + #define LOCAL_SIZE_Z 1u + #define LOCAL_SIZE (LOCAL_SIZE_X * LOCAL_SIZE_Y * LOCAL_SIZE_Z) #pragma rate CCConst pass layout(std140) uniform CCConst { @@ -23,18 +26,23 @@ CCProgram cluster-main %{ }; #pragma rate b_ccLightsBuffer pass + #pragma glBinding(0) layout(std430) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; }; #pragma rate b_clustersBuffer pass + #pragma glBinding(1) layout(std430) readonly buffer b_clustersBuffer { vec4 b_clusters[]; }; #pragma rate b_clusterLightIndicesBuffer pass + #pragma glBinding(2) layout(std430) buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; }; #pragma rate b_clusterLightGridBuffer pass + #pragma glBinding(3) layout(std430) buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; }; #pragma rate b_globalIndexBuffer pass + #pragma glBinding(4) layout(std430) buffer b_globalIndexBuffer { uint b_globalIndex[]; }; struct CCLight { @@ -42,6 +50,7 @@ CCProgram cluster-main %{ vec4 cc_lightColor; vec4 cc_lightSizeRangeAngle; vec4 cc_lightDir; + vec4 cc_lightBoundingSizeVS; }; uint ccLightCount() { @@ -50,10 +59,11 @@ CCProgram cluster-main %{ CCLight getCCLight(uint i) { CCLight light; - light.cc_lightPos = b_ccLights[4u * i + 0u]; - light.cc_lightColor = b_ccLights[4u * i + 1u]; - light.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u]; - light.cc_lightDir = b_ccLights[4u * i + 3u]; + light.cc_lightPos = b_ccLights[5u * i + 0u]; + light.cc_lightColor = b_ccLights[5u * i + 1u]; + light.cc_lightSizeRangeAngle = b_ccLights[5u * i + 2u]; + light.cc_lightDir = b_ccLights[5u * i + 3u]; + light.cc_lightBoundingSizeVS = b_ccLights[5u * i + 4u]; return light; } struct Cluster { @@ -94,8 +104,8 @@ CCProgram cluster-main %{ vec3 dist = closest - light.cc_lightPos.xyz; return dot(dist, dist) <= (light.cc_lightSizeRangeAngle.y * light.cc_lightSizeRangeAngle.y); } - shared CCLight lights[(16 * 8 * LOCAL_SIZE_Z)]; - layout(local_size_x = 16, local_size_y = 8, local_size_z = LOCAL_SIZE_Z) in; + shared CCLight lights[LOCAL_SIZE]; + layout(local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in; void main() { uint visibleLights[100]; @@ -108,7 +118,7 @@ CCProgram cluster-main %{ uint lightCount = ccLightCount(); uint lightOffset = 0u; while (lightOffset < lightCount) { - uint batchSize = min((16u * 8u * uint(LOCAL_SIZE_Z)), lightCount - lightOffset); + uint batchSize = min(LOCAL_SIZE, lightCount - lightOffset); if (uint(gl_LocalInvocationIndex) < batchSize) { uint lightIndex = lightOffset + gl_LocalInvocationIndex; CCLight light = getCCLight(lightIndex); diff --git a/editor/assets/effects/pipeline/deferred-lighting.effect b/editor/assets/effects/pipeline/deferred-lighting.effect index 7c8c89dff08..b5371e49dc4 100644 --- a/editor/assets/effects/pipeline/deferred-lighting.effect +++ b/editor/assets/effects/pipeline/deferred-lighting.effect @@ -6,9 +6,10 @@ CCEffect %{ - vert: lighting-vs frag: lighting-fs pass: deferred-lighting + rasterizerState: + cullMode: none depthStencilState: - depthFunc: greater - depthTest: true + depthTest: false depthWrite: false }% @@ -29,6 +30,87 @@ CCProgram lighting-vs %{ } }% +CCProgram lighting-fs-tiled %{ + precision highp float; + #include + #include + #include +#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1 + #include +#endif + #include + #include + #include + #include + #include + + #pragma subpass + #pragma subpassColor in albedoMap + #pragma subpassColor in normalMap + #pragma subpassColor in emissiveMap + #pragma subpassDepth in depthStencil + + layout(location = 0) out vec4 fragColor; + + vec4 screen2WS(vec3 coord) { + vec3 ndc = vec3( + 2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0, + 2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0, + #if __VERSION__ >= 450 + coord.z); + #else + 2.0 * coord.z - 1.0); + #endif + + + CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(ndc.y); + return GetWorldPosFromNDCPosRH(ndc, cc_matProj, cc_matViewProjInv); + } + + void main () { + StandardSurface s; + + vec4 albedo = subpassLoad(albedoMap); + vec4 normal = subpassLoad(normalMap); + vec4 emissive = subpassLoad(emissiveMap); + float depth = subpassLoad(depthStencil).x; + + s.albedo = albedo; + vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz; + s.position = position; + s.roughness = normal.z; + s.normal = oct_to_float32x3(normal.xy); + s.specularIntensity = 0.5; + s.metallic = normal.w; + s.emissive = emissive.xyz; + s.occlusion = emissive.w; +#if CC_RECEIVE_SHADOW + s.shadowBias = vec2(0, 0); +#endif + // fixme: default value is 0, and give black result + float fogFactor; + CC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor); + + vec4 shadowPos; + CC_TRANSFER_SHADOW_BASE(vec4(position, 1), shadowPos); + + vec4 color = CCStandardShadingBase(s, shadowPos) + +#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1 + CCClusterShadingAdditive(s, shadowPos); +#else + CCStandardShadingAdditive(s, shadowPos); +#endif + CC_APPLY_FOG_BASE(color, fogFactor); + color = CCFragOutput(color); + +#if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_SINGLE + color = vec4(albedoMap.rgb, 1.0); +#endif + + fragColor = color; + } +}% + CCProgram lighting-fs %{ precision highp float; #include @@ -44,15 +126,14 @@ CCProgram lighting-fs %{ #include in vec2 v_uv; - - #pragma rate gbuffer_albedoMap pass - layout(binding = 0) uniform sampler2D gbuffer_albedoMap; - #pragma rate gbuffer_normalMap pass - layout(binding = 1) uniform sampler2D gbuffer_normalMap; - #pragma rate gbuffer_emissiveMap pass - layout(binding = 2) uniform sampler2D gbuffer_emissiveMap; - #pragma rate depth_stencil pass - layout(binding = 3) uniform sampler2D depth_stencil; + #pragma rate albedoMap pass + layout(binding = 0) uniform sampler2D albedoMap; + #pragma rate normalMap pass + layout(binding = 1) uniform sampler2D normalMap; + #pragma rate emissiveMap pass + layout(binding = 2) uniform sampler2D emissiveMap; + #pragma rate depthStencil pass + layout(binding = 3) uniform sampler2D depthStencil; layout(location = 0) out vec4 fragColor; @@ -65,27 +146,31 @@ CCProgram lighting-fs %{ #else 2.0 * coord.z - 1.0); #endif - + + CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(ndc.y); return GetWorldPosFromNDCPosRH(ndc, cc_matProj, cc_matViewProjInv); } void main () { StandardSurface s; - vec4 albedoMap = texture(gbuffer_albedoMap,v_uv); - vec4 normalMap = texture(gbuffer_normalMap,v_uv); - vec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv); - float depth = texture(depth_stencil, v_uv).x; + vec4 albedo = texture(albedoMap, v_uv); + vec4 normal = texture(normalMap, v_uv); + vec4 emissive = texture(emissiveMap, v_uv); + float depth = texture(depthStencil, v_uv).x; - s.albedo = albedoMap; + s.albedo = albedo; vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz; s.position = position; - s.roughness = normalMap.z; - s.normal = oct_to_float32x3(normalMap.xy); + s.roughness = normal.z; + s.normal = oct_to_float32x3(normal.xy); s.specularIntensity = 0.5; - s.metallic = normalMap.w; - s.emissive = emissiveMap.xyz; - s.occlusion = emissiveMap.w; + s.metallic = normal.w; + s.emissive = emissive.xyz; + s.occlusion = emissive.w; +#if CC_RECEIVE_SHADOW + s.shadowBias = vec2(0, 0); +#endif // fixme: default value is 0, and give black result float fogFactor; CC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor); diff --git a/editor/assets/effects/pipeline/post-process.effect b/editor/assets/effects/pipeline/post-process.effect index 302899d1f13..aa9ca7056d0 100644 --- a/editor/assets/effects/pipeline/post-process.effect +++ b/editor/assets/effects/pipeline/post-process.effect @@ -33,7 +33,6 @@ CCProgram post-process-vs %{ CCDecode(In); CC_HANDLE_GET_CLIP_FLIP(In.position.xy); gl_Position = In.position; - gl_Position.y = gl_Position.y; v_uv = a_texCoord; } }% diff --git a/editor/assets/effects/pipeline/skybox.effect b/editor/assets/effects/pipeline/skybox.effect index f9513c2d99f..04c16fc0bf1 100644 --- a/editor/assets/effects/pipeline/skybox.effect +++ b/editor/assets/effects/pipeline/skybox.effect @@ -6,11 +6,18 @@ CCEffect %{ properties: &props environmentMap: { value: grey } priority: max - 10 - rasterizerState: + rasterizerState: &r1 cullMode: none - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false + - vert: sky-vs:vert + frag: sky-fs:frag + propertyIndex: 0 + priority: max - 10 + phase: deferred-forward + rasterizerState: *r1 + depthStencilState: *d1 }% CCProgram sky-vs %{ diff --git a/editor/assets/effects/util/dcc/imported-metallic-roughness.effect b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect index 780c2a32522..a385d707dde 100644 --- a/editor/assets/effects/util/dcc/imported-metallic-roughness.effect +++ b/editor/assets/effects/util/dcc/imported-metallic-roughness.effect @@ -60,15 +60,20 @@ CCEffect %{ mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } alphaSource: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } alphaSourceMap: { value: grey, editor: { parent: USE_OPACITY_MAP } } + - &deferred-forward + vert: standard-vs + frag: standard-fs + propertyIndex: 0 + phase: deferred-forward - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -77,6 +82,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -284,7 +297,7 @@ CCProgram surface-fragment %{ #else emissiveColor.rgb *= emissiveScale; #endif - + return emissiveColor.rgb; } @@ -297,7 +310,7 @@ CCProgram surface-fragment %{ #if USE_OCCLUSION_MAP vec4 occlusionColor = texture(occlusionMap, TEXTURE_UV); float occlusionColorValue = discolor(occlusionColor.rgb); - #if USE_OCCLUSION_CHANNEL + #if USE_OCCLUSION_CHANNEL occlusionColor.rgb = SRGBToLinear(occlusionColor.rgb); occlusionColorValue = occlusionColor.OCCLUSION_CHANNEL; #endif @@ -310,7 +323,7 @@ CCProgram surface-fragment %{ #if USE_ROUGHNESS_MAP vec4 roughnessColor = texture(roughnessMap, TEXTURE_UV); roughnessValue = discolor(roughnessColor.rgb); - #if USE_ROUGHNESS_CHANNEL + #if USE_ROUGHNESS_CHANNEL roughnessColor.rgb = SRGBToLinear(roughnessColor.rgb); roughnessValue = roughnessColor.ROUGHNESS_CHANNEL; #endif @@ -323,7 +336,7 @@ CCProgram surface-fragment %{ #if USE_METALLIC_MAP vec4 metallicColor = texture(metallicMap, TEXTURE_UV); metallicValue = discolor(metallicColor.rgb); - #if USE_METALLIC_CHANNEL + #if USE_METALLIC_CHANNEL metallicColor.rgb = SRGBToLinear(metallicColor.rgb); metallicValue = metallicColor.METALLIC_CHANNEL; #endif diff --git a/editor/assets/effects/util/dcc/imported-specular-glossiness.effect b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect index 246ee9232e4..fe4565b98bc 100644 --- a/editor/assets/effects/util/dcc/imported-specular-glossiness.effect +++ b/editor/assets/effects/util/dcc/imported-specular-glossiness.effect @@ -8,7 +8,7 @@ CCEffect %{ frag: standard-fs properties: &props mainTexture: { value: grey, target: albedoMap, editor: { displayName: DiffuseMap } } - mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: diffuseColor, linear: true, editor: { displayName: DiffuseColor, type: color } } + mainColor: { value: [1.0, 1.0, 1.0, 1.0], target: diffuseColor, linear: true, editor: { displayName: DiffuseColor, type: color } } albedoScale: { value: 1.0, target: diffuseFactor, editor: { displayName: diffuseFactor } } alphaThreshold: { value: 0.5, editor: { parent: USE_ALPHA_TEST, slide: true, range: [0, 1.0], step: 0.001 } } emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } @@ -18,10 +18,10 @@ CCEffect %{ shininessExponentMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } shininessExponent: { value: 100.0, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } specularGlossinessMap: { value: grey, editor: { parent: '!HAS_EXPORTED_GLOSSINESS' } } - specularColor: { value: [0.0, 0.0, 0.0, 0.0], linear: true, editor: { displayName: SpecularColor, type: color } } + specularColor: { value: [0.0, 0.0, 0.0, 0.0], linear: true, editor: { displayName: SpecularColor, type: color } } specularMap: { value: grey, editor: { parent: '!HAS_EXPORTED_METALLIC' } } specularFactor: { value: 1.0, editor: { parent: '!HAS_EXPORTED_METALLIC' } } - transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } + transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } transparencyFactor: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } normalStrength: { value: 1.0, target: normalScale, editor: { displayName: bumpFactor, parent: USE_NORMAL_MAP, slide: true, range: [0, 5.0], step: 0.001 } } @@ -60,25 +60,37 @@ CCEffect %{ albedoScale: { value: 1.0, target: diffuseFactor, editor: { displayName: diffuseFactor } } alphaThreshold: { value: 0.5, editor: { parent: USE_ALPHA_TEST } } mainTexture: { value: grey, target: albedoMap, editor: { displayName: AlbedoMap } } - transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } + transparencyMap: { value: grey, editor: { displayName: TransparencyMap } } transparencyFactor: { value: 1.0, editor: { slide: true, range: [0, 1.0], step: 0.001 } } + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha - properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -169,7 +181,7 @@ CCProgram surface-fragment %{ uniform sampler2D transparencyMap; #pragma define-meta TRANSPARENCY_MAP_CHANNEL options([a, r, g, b]) #endif - + #if USE_EMISSIVE_MAP uniform sampler2D emissiveMap; #endif @@ -220,7 +232,7 @@ CCProgram surface-fragment %{ #endif return specularIntensityMultiplier; } - + vec4 getSpecularColorAndFactor() { vec3 inSpecular = specularColor.rgb * specularFactor; @@ -271,7 +283,7 @@ CCProgram surface-fragment %{ #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE vec3 SurfacesFragmentModifyEmissive() - { + { vec3 emissiveColor = emissive.rgb; #if USE_EMISSIVE_MAP emissiveColor.rgb = SRGBToLinear(texture(emissiveMap, TEXTURE_UV).rgb); @@ -284,7 +296,7 @@ CCProgram surface-fragment %{ #else emissiveColor.rgb *= emissiveScale; #endif - + return emissiveColor; } diff --git a/editor/assets/effects/util/dcc/vat/houdini-fluid-v3-liquid.effect b/editor/assets/effects/util/dcc/vat/houdini-fluid-v3-liquid.effect index 30499e69a8d..25d9e5c09f8 100644 --- a/editor/assets/effects/util/dcc/vat/houdini-fluid-v3-liquid.effect +++ b/editor/assets/effects/util/dcc/vat/houdini-fluid-v3-liquid.effect @@ -47,7 +47,7 @@ CCEffect %{ vatRotSignMap: { value: white, target: vatRotSignTexture, editor: { displayName: RotSignMap } } vatRotAlphaMap: { value: grey, target: vatRotAlphaTexture, editor: { displayName: RotAlphaMap } } vatLookupMap: { value: grey, target: vatLookupTexture, editor: { parent: USE_LOOKUP_TEXTURE, displayName: LookupMap } } - rasterizerState: + rasterizerState: &r1 cullMode: none - &forward-add vert: standard-vs @@ -85,15 +85,21 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -102,6 +108,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -153,7 +167,7 @@ CCProgram surface-vertex %{ #if USE_LOOKUP_TEXTURE uniform highp sampler2D vatLookupTexture; #endif - + #define CC_SURFACES_VERTEX_MODIFY_LOCAL_POS vec3 SurfacesVertexModifyLocalPos(in SurfacesStandardVertexIntermediate In) { @@ -233,7 +247,7 @@ CCProgram surface-vertex %{ vec3 voxelUV = VATCalculateFluidVoxelUV(vatBBMin.xyz, vatBBMax.xyz, In.position.xyz); In.texCoord = voxelUV.xz; #endif - } + } }% CCProgram surface-fragment %{ @@ -369,7 +383,7 @@ void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingI float multiplier = 1.0 + pow(1.0 - curve, 0.3) * vatLUTParams.w; result.environmentSpecular *= multiplier; #endif - + #if CC_SURFACES_LIGHTING_USE_FRESNEL result.fresnel = GetFresnel(result.fresnel); #endif diff --git a/editor/assets/effects/util/dcc/vat/houdini-rigidbody-v2.effect b/editor/assets/effects/util/dcc/vat/houdini-rigidbody-v2.effect index 34bc0b6d826..9cdff2b1a97 100644 --- a/editor/assets/effects/util/dcc/vat/houdini-rigidbody-v2.effect +++ b/editor/assets/effects/util/dcc/vat/houdini-rigidbody-v2.effect @@ -39,7 +39,7 @@ CCEffect %{ vatRotationMap: { value: grey, target: vatRotationTexture, editor: { displayName: RotationMap } } vatRotSignMap: { value: white, target: vatRotSignTexture, editor: { displayName: RotSignMap } } vatRotAlphaMap: { value: grey, target: vatRotAlphaTexture, editor: { displayName: RotAlphaMap } } - rasterizerState: + rasterizerState: &r1 cullMode: none - &forward-add vert: standard-vs @@ -77,15 +77,21 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -94,6 +100,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -113,7 +127,7 @@ CCProgram macro-remapping %{ // ui displayed macros #pragma define-meta USE_TWOSIDE #pragma define-meta IS_ANISOTROPY - #pragma define-meta USE_VERTEX_COLOR + #pragma define-meta USE_VERTEX_COLOR #define CC_SURFACES_USE_SECOND_UV 1 #define CC_SURFACES_USE_TWO_SIDED USE_TWOSIDE #define CC_SURFACES_LIGHTING_ANISOTROPIC IS_ANISOTROPY @@ -164,11 +178,11 @@ CCProgram surface-vertex %{ #endif #if CC_SURFACES_USE_TANGENT_SPACE vec3 tangent = In.tangent.xzy; - #else + #else vec3 tangent = vec3(0.0); - #endif + #endif - VATGetLocalPositionRigidBody20_UE(In.position.xyz, In.normal.xyz, tangent, color, thisFrameUV, + VATGetLocalPositionRigidBody20_UE(In.position.xyz, In.normal.xyz, tangent, color, thisFrameUV, vatMaxMin.x, vatMaxMin.y, vatMaxMin.z, vatMaxMin.w, vatPositionTexture, vatPosSignTexture, vatPosAlphaTexture, vatRotationTexture, vatRotSignTexture, vatRotAlphaTexture); @@ -217,7 +231,7 @@ CCProgram surface-fragment %{ vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 baseColor = albedo; - + #if USE_ALBEDO_MAP vec4 texColor = texture(albedoMap, ALBEDO_UV); texColor.rgb = SRGBToLinear(texColor.rgb); @@ -243,7 +257,7 @@ CCProgram surface-fragment %{ #if USE_ALBEDO_MAP alpha = texture(albedoMap, ALBEDO_UV).ALPHA_TEST_CHANNEL; #endif - + if (alpha < albedoScaleAndCutoff.w) discard; #endif } diff --git a/editor/assets/effects/util/dcc/vat/houdini-softbody-v3.effect b/editor/assets/effects/util/dcc/vat/houdini-softbody-v3.effect index 0a09914bc0b..1e6be194e54 100644 --- a/editor/assets/effects/util/dcc/vat/houdini-softbody-v3.effect +++ b/editor/assets/effects/util/dcc/vat/houdini-softbody-v3.effect @@ -33,7 +33,7 @@ CCEffect %{ vatRotationMap: { value: grey, target: vatRotationTexture, editor: { displayName: RotationMap } } vatRotSignMap: { value: white, target: vatRotSignTexture, editor: { displayName: RotSignMap } } vatRotAlphaMap: { value: grey, target: vatRotAlphaTexture, editor: { displayName: RotAlphaMap } } - rasterizerState: + rasterizerState: &r1 cullMode: none - &forward-add vert: standard-vs @@ -71,23 +71,36 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha - properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -224,7 +237,7 @@ CCProgram surface-fragment %{ vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 baseColor = albedo; - + #if USE_VERTEX_COLOR baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear baseColor.a *= FSInput_vertexColor.a; @@ -255,7 +268,7 @@ CCProgram surface-fragment %{ #if USE_ALBEDO_MAP alpha = texture(albedoMap, ALBEDO_UV).ALPHA_TEST_CHANNEL; #endif - + if (alpha < albedoScaleAndCutoff.w) discard; #endif } diff --git a/editor/assets/effects/util/dcc/vat/zeno-fluid-liquid.effect b/editor/assets/effects/util/dcc/vat/zeno-fluid-liquid.effect index 0ef61d3b403..dee64a0c75a 100644 --- a/editor/assets/effects/util/dcc/vat/zeno-fluid-liquid.effect +++ b/editor/assets/effects/util/dcc/vat/zeno-fluid-liquid.effect @@ -36,7 +36,7 @@ CCEffect %{ waterScatterCoef: { value: 3.0, target: waterColor.w, editor: { parent: USE_WATER_SCATTERING, range: [0, 10.0] } } vatPositionMap: { value: grey, target: vatPositionTexture, editor: { displayName: PositionMap } } vatNormalMap: { value: grey, target: vatNormalTexture } - rasterizerState: + rasterizerState: &r1 cullMode: none - &forward-add vert: standard-vs @@ -73,15 +73,21 @@ CCEffect %{ frag: reflect-map-fs phase: reflect-map propertyIndex: 0 + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + propertyIndex: 0 + rasterizerState: *r1 - name: transparent passes: - vert: standard-vs frag: standard-fs embeddedMacros: { CC_FORCE_FORWARD_SHADING: true } - depthStencilState: + depthStencilState: &d1 depthTest: true depthWrite: false - blendState: + blendState: &b1 targets: - blend: true blendSrc: src_alpha @@ -90,6 +96,14 @@ CCEffect %{ properties: *props - *forward-add - *shadow-caster + - &deferred-forward + vert: standard-vs + frag: standard-fs + phase: deferred-forward + embeddedMacros: { CC_PIPELINE_TYPE: 0 } + depthStencilState: *d1 + blendState: *b1 + propertyIndex: 0 }% CCProgram shared-ubos %{ @@ -156,7 +170,7 @@ CCProgram surface-vertex %{ // pos is normalized 0-1 from texture and expanding to bounding box range vec3 posNormalized = SampleTextureExr(vatPositionTexture, thisFrameUV); In.position.xyz = posNormalized * (vatBBMax.xyz - vatBBMin.xyz) + vatBBMin.xyz; - + vec3 normal = texture(vatNormalTexture, thisFrameUV).rgb * 2.0 - 1.0; In.normal.xyz = normalize(normal); } @@ -253,7 +267,7 @@ CCProgram surface-fragment %{ { return vatAnimParams.w; } - + #define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_SCATTERING_PARAMS vec4 SurfacesFragmentModifyTransmitScatteringParams() { @@ -264,7 +278,7 @@ CCProgram surface-fragment %{ return vec4(0.0, 0.0, 0.0, 0.0); #endif } - + #define CC_SURFACES_FRAGMENT_MODIFY_TRANSMIT_IN_SCATTERING_COLOR vec3 SurfacesFragmentModifyTransmitInScatteringColor() { @@ -284,7 +298,7 @@ CCProgram surface-fragment %{ vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 baseColor = albedo; - + #if USE_VERTEX_COLOR baseColor.rgb *= SRGBToLinear(FSInput_vertexColor.rgb); // use linear baseColor.a *= FSInput_vertexColor.a; @@ -306,7 +320,7 @@ CCProgram surface-fragment %{ #if USE_VERTEX_COLOR alpha *= FSInput_vertexColor.a; #endif - + if (alpha < albedoScaleAndCutoff.w) discard; #endif } @@ -331,7 +345,7 @@ void SurfacesLightingModifyFinalResult(inout LightingResult result, in LightingI float multiplier = 1.0 + pow(1.0 - curve, 0.3) * vatLUTParams.w; result.environmentSpecular *= multiplier; #endif - + #if CC_SURFACES_LIGHTING_USE_FRESNEL result.fresnel = GetFresnel(result.fresnel); #endif diff --git a/native/cocos/renderer/gfx-base/GFXBarrier.cpp b/native/cocos/renderer/gfx-base/GFXBarrier.cpp index 165532b5343..688c9a42612 100644 --- a/native/cocos/renderer/gfx-base/GFXBarrier.cpp +++ b/native/cocos/renderer/gfx-base/GFXBarrier.cpp @@ -248,10 +248,10 @@ constexpr AccessElem ACCESS_MAP[] = { ACCESS_READ | RES_BUFFER | SHADERSTAGE_FRAG | CMN_ROM, AccessFlags::FRAGMENT_SHADER_READ_UNIFORM_BUFFER}, - {IGNORE_MEMUSAGE, + {CARE_MEMACCESS | CARE_RESTYPE | CARE_SHADERSTAGE | CARE_CMNUSAGE, ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_ROM, AccessFlags::FRAGMENT_SHADER_READ_TEXTURE, - CMN_STORAGE}, + CMN_STORAGE | CMN_VB_OR_DS}, {IGNORE_MEMUSAGE, ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA | CMN_INDIRECT_OR_INPUT, @@ -270,9 +270,9 @@ constexpr AccessElem ACCESS_MAP[] = { // ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA, // AccessFlags::COLOR_ATTACHMENT_READ}, - //{IGNORE_MEMUSAGE, - // ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_VB_OR_DS, - // AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ}, + {CARE_MEMACCESS | CARE_RESTYPE | CARE_CMNUSAGE, + ACCESS_READ | RES_TEXTURE | CMN_VB_OR_DS | CMN_ROM, + AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ}, {IGNORE_MEMUSAGE, ACCESS_READ | RES_BUFFER | SHADERSTAGE_COMP | CMN_ROM, diff --git a/native/cocos/renderer/gfx-base/GFXDevice.cpp b/native/cocos/renderer/gfx-base/GFXDevice.cpp index bb127c6ad99..c8e8805d26a 100644 --- a/native/cocos/renderer/gfx-base/GFXDevice.cpp +++ b/native/cocos/renderer/gfx-base/GFXDevice.cpp @@ -166,6 +166,14 @@ DefaultResource::DefaultResource(Device *device) { region.texSubres.baseArrayLayer = 1; device->copyBuffersToTexture(&bufferData, _texture2DArray, ®ion, 1); } + { + BufferInfo bufferInfo = {}; + bufferInfo.usage = BufferUsageBit::STORAGE | BufferUsageBit::TRANSFER_DST | BufferUsageBit::TRANSFER_SRC | BufferUsageBit::VERTEX | BufferUsageBit::INDEX | BufferUsageBit::INDIRECT; + bufferInfo.memUsage = MemoryUsageBit::DEVICE | MemoryUsageBit::HOST; + bufferInfo.size = 5 * sizeof(uint32_t); // for indirect command buffer + bufferInfo.stride = bufferInfo.size; + _buffer = device->createBuffer(bufferInfo); + } } Texture *DefaultResource::getTexture(TextureType type) const { @@ -184,5 +192,9 @@ Texture *DefaultResource::getTexture(TextureType type) const { } } +Buffer *DefaultResource::getBuffer() const { + return _buffer; +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-base/GFXDevice.h b/native/cocos/renderer/gfx-base/GFXDevice.h index 692b2da4248..c9f2c3f9efe 100644 --- a/native/cocos/renderer/gfx-base/GFXDevice.h +++ b/native/cocos/renderer/gfx-base/GFXDevice.h @@ -199,12 +199,14 @@ class DefaultResource { ~DefaultResource() = default; Texture *getTexture(TextureType type) const; + Buffer *getBuffer() const; private: IntrusivePtr _texture2D; IntrusivePtr _texture2DArray; IntrusivePtr _textureCube; IntrusivePtr _texture3D; + IntrusivePtr _buffer; }; ////////////////////////////////////////////////////////////////////////// diff --git a/native/cocos/renderer/gfx-gles2/GLES2Device.cpp b/native/cocos/renderer/gfx-gles2/GLES2Device.cpp index 1b25d640e41..431aff68202 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Device.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Device.cpp @@ -128,7 +128,12 @@ bool GLES2Device::doInit(const DeviceInfo & /*info*/) { ccstd::string fbfLevelStr = "NONE"; // PVRVFrame has issues on their support -#if CC_PLATFORM != CC_PLATFORM_WINDOWS +#ifndef ENABLE_GLES2_SUBPASS + _features[toNumber(Feature::INPUT_ATTACHMENT_BENEFIT)] = false; + _features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = false; + _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = false; + _features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = false; +#elif CC_PLATFORM != CC_PLATFORM_WINDOWS if (checkExtension("framebuffer_fetch")) { ccstd::string nonCoherent = "framebuffer_fetch_non"; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index c063cad07d4..c16915ff5a0 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -714,7 +714,7 @@ void cmdFuncGLES3DestroyBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer) { ccstd::vector &ssbo = device->stateCache()->glBindSSBOs; for (GLuint i = 0; i < ssbo.size(); i++) { if (ssbo[i] == gpuBuffer->glBuffer) { - GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, i, 0)); + GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, 0)); device->stateCache()->glShaderStorageBuffer = 0; ssbo[i] = 0; } @@ -1211,6 +1211,7 @@ void cmdFuncGLES3CreateShader(GLES3Device *device, GLES3GPUShader *gpuShader, GL gpuShader->glBuffers.resize(blockCount + bufferCount); + GLuint uboBinding = 0; for (GLint i = 0; i < blockCount; ++i) { GLES3GPUUniformBuffer &glBlock = gpuShader->glBuffers[i]; memset(glName, 0, sizeof(glName)); @@ -1229,8 +1230,9 @@ void cmdFuncGLES3CreateShader(GLES3Device *device, GLES3GPUShader *gpuShader, GL if (block.name == glBlock.name) { glBlock.set = block.set; glBlock.binding = block.binding; - glBlock.glBinding = block.binding + device->bindingMappings().blockOffsets[block.set]; - GL_CHECK(glUniformBlockBinding(gpuShader->glProgram, i, glBlock.glBinding)); + glBlock.glBinding = uboBinding; + GL_CHECK(glUniformBlockBinding(gpuShader->glProgram, i, uboBinding)); + uboBinding += block.count; break; } } diff --git a/native/cocos/renderer/gfx-gles3/GLES3DescriptorSet.cpp b/native/cocos/renderer/gfx-gles3/GLES3DescriptorSet.cpp index bc9128083f7..c75d194327a 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3DescriptorSet.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3DescriptorSet.cpp @@ -29,6 +29,7 @@ #include "GLES3DescriptorSet.h" #include "GLES3DescriptorSetLayout.h" #include "GLES3Texture.h" +#include "GLES3Device.h" #include "gfx-gles3/GLES3GPUObjects.h" #include "states/GLES3Sampler.h" @@ -73,12 +74,24 @@ void GLES3DescriptorSet::update() { descriptors[i].gpuBuffer = static_cast(_buffers[i].ptr)->gpuBuffer(); } } else if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_TEXTURE_TYPE)) { - if (_textures[i].ptr) { - _gpuDescriptorSet->gpuDescriptors[i].gpuTextureView = static_cast(_textures[i].ptr)->gpuTextureView(); - } if (_samplers[i].ptr) { descriptors[i].gpuSampler = static_cast(_samplers[i].ptr)->gpuSampler(); } + + if (_textures[i].ptr) { + _gpuDescriptorSet->gpuDescriptors[i].gpuTextureView = static_cast(_textures[i].ptr)->gpuTextureView(); + + // work around for sample depth stencil texture, delete when rdg support set sampler. + const FormatInfo &info = GFX_FORMAT_INFOS[toNumber( + _textures[i].ptr->getFormat())]; + if (info.hasDepth || info.hasStencil) { + gfx::SamplerInfo samplerInfo = {}; + samplerInfo.minFilter = gfx::Filter::POINT; + samplerInfo.magFilter = gfx::Filter::POINT; + descriptors[i].gpuSampler = static_cast(Device::getInstance()->getSampler( + samplerInfo))->gpuSampler(); + } + } } } _isDirty = false; diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm index 79eba7a43a2..0779591c601 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm @@ -39,6 +39,7 @@ of this software and associated engine source code (the "Software"), a limited, #import "MTLSemaphore.h" #import "MTLSwapchain.h" #import "MTLTexture.h" +#import "MTLShader.h" #import "TargetConditionals.h" #import "profiler/Profiler.h" #import "base/Log.h" @@ -1033,12 +1034,15 @@ of this software and associated engine source code (the "Software"), a limited, bindDescriptorSets(); } MTLSize groupsPerGrid = MTLSizeMake(info.groupCountX, info.groupCountY, info.groupCountZ); + auto* ccShader = static_cast(_gpuCommandBufferObj->pipelineState->getShader()); + const auto& groupSize = ccShader->gpuShader(nullptr, 0)->workGroupSize; + MTLSize workGroupSize = MTLSizeMake(groupSize[0], groupSize[1], groupSize[2]); if (info.indirectBuffer) { auto* ccBuffer = static_cast(info.indirectBuffer); // offset: [dispatch offset] + [backbuffer offset] - _computeEncoder.dispatch(ccBuffer->mtlBuffer(), info.indirectOffset + ccBuffer->currentOffset(), groupsPerGrid); + _computeEncoder.dispatch(ccBuffer->mtlBuffer(), info.indirectOffset + ccBuffer->currentOffset(), workGroupSize); } else { - _computeEncoder.dispatch(groupsPerGrid); + _computeEncoder.dispatch(groupsPerGrid, workGroupSize); } _computeEncoder.endEncoding(); } diff --git a/native/cocos/renderer/gfx-metal/MTLComputeCommandEncoder.h b/native/cocos/renderer/gfx-metal/MTLComputeCommandEncoder.h index eeea0c08dd3..c7bbac2a5f6 100644 --- a/native/cocos/renderer/gfx-metal/MTLComputeCommandEncoder.h +++ b/native/cocos/renderer/gfx-metal/MTLComputeCommandEncoder.h @@ -76,9 +76,13 @@ class CCMTLComputeCommandEncoder final : public CCMTLCommandEncoder { MTLSize threadsPerThreadgroup = MTLSizeMake(w, h, 1); [_mtlEncoder dispatchThreadgroups:groupsPerGrid threadsPerThreadgroup:threadsPerThreadgroup]; } + + inline void dispatch(MTLSize groupsPerGrid, MTLSize workGroupSize) { + [_mtlEncoder dispatchThreadgroups:groupsPerGrid threadsPerThreadgroup:workGroupSize]; + } - inline void dispatch(id indirectBuffer, NSUInteger offset, MTLSize groupsPerGrid) { - [_mtlEncoder dispatchThreadgroupsWithIndirectBuffer:indirectBuffer indirectBufferOffset:offset threadsPerThreadgroup:groupsPerGrid]; + inline void dispatch(id indirectBuffer, NSUInteger offset, MTLSize localSize) { + [_mtlEncoder dispatchThreadgroupsWithIndirectBuffer:indirectBuffer indirectBufferOffset:offset threadsPerThreadgroup:localSize]; } inline void endEncoding() { diff --git a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h index 48a0243eb79..63a772f2080 100644 --- a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h +++ b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h @@ -34,6 +34,7 @@ #import "MTLDevice.h" #import "MTLUtils.h" #include "base/std/container/queue.h" +#include namespace cc { namespace gfx { @@ -111,6 +112,8 @@ struct CCMTLGPUShader { ccstd::vector inputs; ccstd::vector outputs; + std::array workGroupSize{0, 0, 0}; + NSString *shaderSrc = nil; bool specializeColor = true; diff --git a/native/cocos/renderer/gfx-metal/MTLShader.mm b/native/cocos/renderer/gfx-metal/MTLShader.mm index b6e8c7546f3..3a81909b736 100644 --- a/native/cocos/renderer/gfx-metal/MTLShader.mm +++ b/native/cocos/renderer/gfx-metal/MTLShader.mm @@ -159,7 +159,7 @@ of this software and associated engine source code (the "Software"), a limited, spirv->initialize(2); // vulkan >= 1.2 spirv >= 1.5 } - spirv->compileGLSL(stage.stage, "#version 450\n" + stage.source); + spirv->compileGLSL(stage.stage, "#version 450\n#define CC_USE_METAL 1\n" + stage.source); if (stage.stage == ShaderStageFlagBit::VERTEX) spirv->compressInputLocations(_attributes); auto* spvData = spirv->getOutputData(); diff --git a/native/cocos/renderer/gfx-metal/MTLUtils.mm b/native/cocos/renderer/gfx-metal/MTLUtils.mm index 7684baf24fe..18869415bba 100644 --- a/native/cocos/renderer/gfx-metal/MTLUtils.mm +++ b/native/cocos/renderer/gfx-metal/MTLUtils.mm @@ -1090,6 +1090,14 @@ void main() { gpuShader->outputs[i].set = set; gpuShader->outputs[i].binding = loc; } + } else if (executionModel == spv::ExecutionModelGLCompute) { + spirv_cross::SpecializationConstant x, y, z; + auto workGroupID = msl.get_work_group_size_specialization_constants(x, y, z); + const auto& workGroupSizeSpv = msl.get_constant(workGroupID); + const auto& workGroupSize = workGroupSizeSpv.vector().r; + gpuShader->workGroupSize[0] = workGroupSize[0].u32; + gpuShader->workGroupSize[1] = workGroupSize[1].u32; + gpuShader->workGroupSize[2] = workGroupSize[2].u32; } // Compile to MSL, ready to give to metal driver. diff --git a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp index b8dca00fcd9..d9bb087abf1 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp @@ -120,7 +120,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { gpuTexture->aspectMask = mapVkImageAspectFlags(gpuTexture->format); // storage images has to be in general layout - if (hasFlag(gpuTexture->usage, TextureUsageBit::STORAGE)) gpuTexture->flags |= TextureFlagBit::GENERAL_LAYOUT; + // if (hasFlag(gpuTexture->usage, TextureUsageBit::STORAGE)) gpuTexture->flags |= TextureFlagBit::GENERAL_LAYOUT; // remove stencil aspect for depth textures with sampled usage if (hasFlag(gpuTexture->usage, TextureUsageBit::SAMPLED)) gpuTexture->aspectMask &= ~VK_IMAGE_ASPECT_STENCIL_BIT; diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index 458f48f8040..b7ab9d3ef86 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -226,6 +226,14 @@ inline bool hasReadAccess(gfx::AccessFlagBit flag) { return (static_cast(flag) & READ_ACCESS) != 0; } +inline bool isAttachmentAccess(gfx::AccessFlagBit flag) { + return hasAnyFlags(flag, gfx::AccessFlagBit::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | + gfx::AccessFlagBit::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT | + gfx::AccessFlagBit::COLOR_ATTACHMENT_READ | + gfx::AccessFlagBit::COLOR_ATTACHMENT_WRITE | + gfx::AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE); +} + inline bool isReadOnlyAccess(gfx::AccessFlagBit flag) { return flag < gfx::AccessFlagBit::PRESENT || flag == gfx::AccessFlagBit::SHADING_RATE; } @@ -1158,42 +1166,61 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { } } - const auto &resDescs = get(ResourceGraph::DescTag{}, resourceGraph); - auto genGFXBarrier = [&resDescs](std::vector &barriers) { - for (auto &passBarrier : barriers) { - const auto &desc = get(resDescs, passBarrier.resourceID); - if (desc.dimension == ResourceDimension::BUFFER) { - gfx::BufferBarrierInfo info; - info.prevAccesses = passBarrier.beginStatus.accessFlag; - info.nextAccesses = passBarrier.endStatus.accessFlag; - const auto &range = ccstd::get(passBarrier.endStatus.range); - info.offset = range.offset; - info.size = range.size; - info.type = passBarrier.type; - passBarrier.barrier = gfx::Device::getInstance()->getBufferBarrier(info); - } else { - gfx::TextureBarrierInfo info; - info.prevAccesses = passBarrier.beginStatus.accessFlag; - info.nextAccesses = passBarrier.endStatus.accessFlag; - const auto &range = ccstd::get(passBarrier.beginStatus.range); - info.baseMipLevel = range.mipLevel; - info.levelCount = range.levelCount; - info.baseSlice = range.firstSlice; - info.sliceCount = range.numSlices; - info.type = passBarrier.type; - passBarrier.barrier = gfx::Device::getInstance()->getTextureBarrier(info); + { + const auto &resDescs = get(ResourceGraph::DescTag{}, resourceGraph); + auto genGFXBarrier = [&resDescs](std::vector &barriers) { + for (auto &passBarrier : barriers) { + const auto &desc = get(resDescs, passBarrier.resourceID); + if (desc.dimension == ResourceDimension::BUFFER) { + gfx::BufferBarrierInfo info; + info.prevAccesses = passBarrier.beginStatus.accessFlag; + info.nextAccesses = passBarrier.endStatus.accessFlag; + const auto &range = ccstd::get(passBarrier.endStatus.range); + info.offset = range.offset; + info.size = range.size; + info.type = passBarrier.type; + passBarrier.barrier = gfx::Device::getInstance()->getBufferBarrier(info); + } else { + gfx::TextureBarrierInfo info; + info.prevAccesses = passBarrier.beginStatus.accessFlag; + info.nextAccesses = passBarrier.endStatus.accessFlag; + const auto &range = ccstd::get(passBarrier.beginStatus.range); + info.baseMipLevel = range.mipLevel; + info.levelCount = range.levelCount; + info.baseSlice = range.firstSlice; + info.sliceCount = range.numSlices; + info.type = passBarrier.type; + passBarrier.barrier = gfx::Device::getInstance()->getTextureBarrier(info); + } + } + }; + + constexpr static bool USING_RENDERPASS_DEP_INSTEAD_OF_BARRIER{true}; + if constexpr (USING_RENDERPASS_DEP_INSTEAD_OF_BARRIER) { + auto prune = [&rag, &renderGraph, &resourceGraph](std::vector& barriers) { + barriers.erase(std::remove_if(barriers.begin(), barriers.end(), [&rag, &renderGraph, &resourceGraph](Barrier &barrier) { + bool fromAttachment = isAttachmentAccess(barrier.beginStatus.accessFlag) || barrier.beginStatus.accessFlag == gfx::AccessFlagBit::NONE; + bool toAttachment = isAttachmentAccess(barrier.endStatus.accessFlag); + return toAttachment; + }), + barriers.end()); + }; + for (auto &passBarrierInfo : batchedBarriers) { + auto &passBarrierNode = passBarrierInfo.second; + prune(passBarrierNode.blockBarrier.frontBarriers); + prune(passBarrierNode.blockBarrier.rearBarriers); } } - }; - // generate gfx barrier - for (auto &passBarrierInfo : batchedBarriers) { - auto &passBarrierNode = passBarrierInfo.second; - genGFXBarrier(passBarrierNode.blockBarrier.frontBarriers); - genGFXBarrier(passBarrierNode.blockBarrier.rearBarriers); - for (auto &subpassBarrier : passBarrierNode.subpassBarriers) { - genGFXBarrier(subpassBarrier.frontBarriers); - genGFXBarrier(subpassBarrier.rearBarriers); + // generate gfx barrier + for (auto &passBarrierInfo : batchedBarriers) { + auto &passBarrierNode = passBarrierInfo.second; + genGFXBarrier(passBarrierNode.blockBarrier.frontBarriers); + genGFXBarrier(passBarrierNode.blockBarrier.rearBarriers); + for (auto &subpassBarrier : passBarrierNode.subpassBarriers) { + genGFXBarrier(subpassBarrier.frontBarriers); + genGFXBarrier(subpassBarrier.rearBarriers); + } } } @@ -1833,34 +1860,22 @@ auto getResourceStatus(PassType passType, const PmrString &name, gfx::MemoryAcce // can't find this resource in layoutdata, not in descriptor so either input or output attachment. gfx::TextureUsage texUsage = gfx::TextureUsage::NONE; + // TODO(Zeqiang): visbility of slot name "_" not found - bool isAttachment = (visibility == gfx::ShaderStageFlags::NONE || gfx::hasFlag(visibility, gfx::ShaderStageFlags::FRAGMENT)) && rasterized; - if (isAttachment) { - vis = gfx::ShaderStageFlags::FRAGMENT; - bool outColorFlag = (desc.flags & ResourceFlags::COLOR_ATTACHMENT) != ResourceFlags::NONE; - bool inputFlag = (desc.flags & ResourceFlags::INPUT_ATTACHMENT) != ResourceFlags::NONE; - bool depthStencilFlag = (desc.flags & ResourceFlags::DEPTH_STENCIL_ATTACHMENT) != ResourceFlags::NONE; - bool shadingRateAttachment = (desc.flags & ResourceFlags::SHADING_RATE) != ResourceFlags::NONE; - - inputFlag &= gfx::hasFlag(memAccess, gfx::MemoryAccess::READ_ONLY); - - if (outColorFlag) texUsage |= gfx::TextureUsage::COLOR_ATTACHMENT; - if (inputFlag) texUsage |= gfx::TextureUsage::INPUT_ATTACHMENT; - if (depthStencilFlag) texUsage |= gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT; - if (shadingRateAttachment) texUsage |= gfx::TextureUsage::SHADING_RATE; - } else { - if (memAccess == gfx::MemoryAccess::READ_ONLY) { - if ((desc.flags & ResourceFlags::INPUT_ATTACHMENT) != ResourceFlags::NONE && rasterized) { - texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::INPUT_ATTACHMENT)); - } else { - texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::SAMPLED | gfx::TextureUsage::STORAGE | gfx::TextureUsage::SHADING_RATE)); - } + if (memAccess == gfx::MemoryAccess::READ_ONLY) { + if ((desc.flags & ResourceFlags::INPUT_ATTACHMENT) != ResourceFlags::NONE && rasterized) { + texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::INPUT_ATTACHMENT)); } else { - texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::STORAGE)); + texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::SAMPLED | gfx::TextureUsage::STORAGE | gfx::TextureUsage::SHADING_RATE | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT)); } + } else { + texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::STORAGE)); + } - CC_ASSERT(vis != gfx::ShaderStageFlags::NONE); + if (vis == gfx::ShaderStageFlags::NONE) { + vis = passType == gfx::PassType::RASTER ? gfx::ShaderStageFlags::FRAGMENT : gfx::ShaderStageFlags::COMPUTE; } + usage = texUsage; accesFlag = gfx::getAccessFlags(texUsage, memAccess, vis); } diff --git a/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp b/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp index f19ceb44783..1854385cd5c 100644 --- a/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp +++ b/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp @@ -346,12 +346,10 @@ gfx::DescriptorSet* getOrCreatePerPassDescriptorSet( void generateConstantMacros( gfx::Device* device, - ccstd::string& constantMacros, - bool clusterEnabled) { + ccstd::string& constantMacros) { constantMacros = StringUtil::format( R"( #define CC_DEVICE_SUPPORT_FLOAT_TEXTURE %d -#define CC_ENABLE_CLUSTERED_LIGHT_CULLING %d #define CC_DEVICE_MAX_VERTEX_UNIFORM_VECTORS %d #define CC_DEVICE_MAX_FRAGMENT_UNIFORM_VECTORS %d #define CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT %d @@ -361,7 +359,6 @@ void generateConstantMacros( )", hasAnyFlags(device->getFormatFeatures(gfx::Format::RGBA32F), gfx::FormatFeature::RENDER_TARGET | gfx::FormatFeature::SAMPLED_TEXTURE), - clusterEnabled ? 1 : 0, device->getCapabilities().maxVertexUniformVectors, device->getCapabilities().maxFragmentUniformVectors, device->hasFeature(gfx::Feature::INPUT_ATTACHMENT_BENEFIT), diff --git a/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.h b/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.h index c1c92b8dcf8..389fd95dbd7 100644 --- a/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.h +++ b/native/cocos/renderer/pipeline/custom/LayoutGraphUtils.h @@ -59,8 +59,7 @@ gfx::DescriptorSet* getOrCreatePerPassDescriptorSet( void generateConstantMacros( gfx::Device* device, - ccstd::string& constantMacros, - bool clusterEnabled); + ccstd::string& constantMacros); void printLayoutGraphData( const LayoutGraphData& lg, std::ostream& oss, diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 91276b4217b..f0646960f14 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -496,6 +496,7 @@ gfx::DescriptorSet* initDescriptorSet( CC_EXPECTS(block.descriptors.size() == block.capacity); auto bindID = block.offset; switch (block.type) { + case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER: case DescriptorTypeOrder::UNIFORM_BUFFER: { for (const auto& d : block.descriptors) { // get uniform block @@ -516,10 +517,6 @@ gfx::DescriptorSet* initDescriptorSet( } break; } - case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER: - // not supported yet - CC_EXPECTS(false); - break; case DescriptorTypeOrder::SAMPLER_TEXTURE: { CC_EXPECTS(newSet); for (const auto& d : block.descriptors) { @@ -607,6 +604,7 @@ gfx::DescriptorSet* initDescriptorSet( // not supported yet CC_EXPECTS(false); break; + case DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER: case DescriptorTypeOrder::STORAGE_BUFFER: CC_EXPECTS(newSet); for (const auto& d : block.descriptors) { @@ -628,14 +626,12 @@ gfx::DescriptorSet* initDescriptorSet( found = true; } } - CC_ENSURES(found); + if (!found) { + newSet->bindBuffer(bindID, defaultResource.getBuffer()); + } bindID += d.count; } break; - case DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER: - // not supported yet - CC_EXPECTS(false); - break; case DescriptorTypeOrder::STORAGE_IMAGE: // not supported yet CC_EXPECTS(newSet); @@ -703,6 +699,7 @@ gfx::DescriptorSet* updatePerPassDescriptorSet( CC_EXPECTS(block.descriptors.size() == block.capacity); auto bindID = block.offset; switch (block.type) { + case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER: case DescriptorTypeOrder::UNIFORM_BUFFER: { for (const auto& d : block.descriptors) { // get uniform block @@ -722,10 +719,6 @@ gfx::DescriptorSet* updatePerPassDescriptorSet( } break; } - case DescriptorTypeOrder::DYNAMIC_UNIFORM_BUFFER: - // not supported yet - CC_EXPECTS(false); - break; case DescriptorTypeOrder::SAMPLER_TEXTURE: { CC_EXPECTS(newSet); for (const auto& d : block.descriptors) { @@ -771,13 +764,24 @@ gfx::DescriptorSet* updatePerPassDescriptorSet( // not supported yet CC_EXPECTS(false); break; - case DescriptorTypeOrder::STORAGE_BUFFER: - // not supported yet - CC_EXPECTS(false); - break; case DescriptorTypeOrder::DYNAMIC_STORAGE_BUFFER: - // not supported yet - CC_EXPECTS(false); + case DescriptorTypeOrder::STORAGE_BUFFER: + CC_EXPECTS(newSet); + for (const auto& d : block.descriptors) { + bool found = false; + CC_EXPECTS(d.count == 1); + if (auto iter = user.buffers.find(d.descriptorID.value); + iter != user.buffers.end()) { + newSet->bindBuffer(bindID, iter->second.get()); + found = true; + } else { + auto* prevBuffer = prevSet.getBuffer(bindID); + CC_ENSURES(prevBuffer); + newSet->bindBuffer(bindID, prevBuffer); + } + auto name = lg.valueNames[d.descriptorID.value]; + bindID += d.count; + } break; case DescriptorTypeOrder::STORAGE_IMAGE: // not supported yet @@ -1577,13 +1581,13 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { if (!pso) { return; } - auto* perInstanceSet = ctx.perInstanceDescriptorSets.at(vertID); + // auto* perInstanceSet = ctx.perInstanceDescriptorSets.at(vertID); // execution ctx.cmdBuff->bindPipelineState(pso); ctx.cmdBuff->bindDescriptorSet( static_cast(pipeline::SetIndex::MATERIAL), pass.getDescriptorSet()); - ctx.cmdBuff->bindDescriptorSet( - static_cast(pipeline::SetIndex::LOCAL), perInstanceSet); + // ctx.cmdBuff->bindDescriptorSet( + // static_cast(pipeline::SetIndex::LOCAL), perInstanceSet); ctx.cmdBuff->bindInputAssembler(ctx.context.fullscreenQuad.quadIA.get()); ctx.cmdBuff->draw(ctx.context.fullscreenQuad.quadIA.get()); } diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 76dea3989e3..badeedd1d8f 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -761,7 +761,7 @@ bool NativePipeline::activate(gfx::Swapchain *swapchainIn) { // generate macros here rather than construct func because _clusterEnabled // switch may be changed in root.ts setRenderPipeline() function which is after // pipeline construct. - generateConstantMacros(device, constantMacros, false); + generateConstantMacros(device, constantMacros); _commandBuffers.resize(1, device->getCommandBuffer()); diff --git a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp index 1e45cad430f..e875936f4cb 100644 --- a/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp @@ -1236,7 +1236,7 @@ void NativeProgramLibrary::init(gfx::Device *deviceIn) { } // generate constant macros string - generateConstantMacros(device, lg.constantMacros, false); + generateConstantMacros(device, lg.constantMacros); } void NativeProgramLibrary::setPipeline(PipelineRuntime *pipelineIn) { diff --git a/native/cocos/renderer/pipeline/custom/test/test.h b/native/cocos/renderer/pipeline/custom/test/test.h index 5138fd2000a..d5d2b5e0458 100644 --- a/native/cocos/renderer/pipeline/custom/test/test.h +++ b/native/cocos/renderer/pipeline/custom/test/test.h @@ -840,7 +840,7 @@ static void runTestGraph(const RenderGraph &renderGraph, const ResourceGraph &re }, \ }, \ { \ - PassType::COMPUTE, \ + PassType::COPY, \ { \ {{"3"}, {"7"}}, \ }, \ @@ -852,7 +852,7 @@ static void runTestGraph(const RenderGraph &renderGraph, const ResourceGraph &re }, \ }, \ { \ - PassType::COMPUTE, \ + PassType::RASTER, \ { \ {{"1"}, {"9"}}, \ }, \ @@ -864,7 +864,7 @@ static void runTestGraph(const RenderGraph &renderGraph, const ResourceGraph &re }, \ }, \ { \ - PassType::COMPUTE, \ + PassType::COPY, \ { \ {{"14"}, {"15"}}, \ }, \ @@ -935,7 +935,7 @@ static void runTestGraph(const RenderGraph &renderGraph, const ResourceGraph &re {"8", 8, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \ }, \ { \ - {"1", 1, cc::gfx::ShaderStageFlagBit::VERTEX}, \ + {"1", 1, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \ {"9", 9, cc::gfx::ShaderStageFlagBit::FRAGMENT}, \ }, \ { \ diff --git a/native/tests/unit-test/src/complicated_barrier_case.cpp b/native/tests/unit-test/src/complicated_barrier_case.cpp index 075fae281f9..ec1f32703e2 100644 --- a/native/tests/unit-test/src/complicated_barrier_case.cpp +++ b/native/tests/unit-test/src/complicated_barrier_case.cpp @@ -132,19 +132,12 @@ TEST(complicatedBarrierTest, test12) { ExpectEq(node2subpassRes2.endStatus.access == MemoryAccessBit::READ_ONLY, true); //node3 + // renderpass info layout instead const auto& node3 = barrierMap.at(3); - ExpectEq(node3.blockBarrier.frontBarriers.size() == 1, true); - ExpectEq(node3.blockBarrier.rearBarriers.size() == 1, true); + ExpectEq(node3.blockBarrier.frontBarriers.empty(), true); + ExpectEq(node3.blockBarrier.rearBarriers.empty(), true); ExpectEq(node3.subpassBarriers.empty(), true); - const auto& node3block = node3.blockBarrier; - ExpectEq(node3block.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node3block.rearBarriers[0].resourceID == 4, true); - ExpectEq(node3block.rearBarriers[0].beginStatus.vertID == 3, true); - ExpectEq(node3block.rearBarriers[0].beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); - ExpectEq(node3block.rearBarriers[0].endStatus.vertID == 3, true); - ExpectEq(node3block.rearBarriers[0].endStatus.access == MemoryAccessBit::READ_ONLY, true); - //node4 const auto& node4 = barrierMap.at(4); //ExpectEq(node4.blockBarrier.frontBarriers.size() == 2, true); @@ -196,41 +189,25 @@ TEST(complicatedBarrierTest, test12) { ExpectEq(res7in5.resourceID == 7, true); ExpectEq(res7in5.beginStatus.vertID == 5, true); ExpectEq(res7in5.endStatus.vertID == 5, true); - ExpectEq(res7in5.beginStatus.passType == PassType::COMPUTE, true); + ExpectEq(res7in5.beginStatus.passType == PassType::COPY, true); ExpectEq(res7in5.endStatus.passType == PassType::COPY, true); ExpectEq(res7in5.beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); ExpectEq(res7in5.endStatus.access == MemoryAccessBit::READ_ONLY, true); const auto& node6 = barrierMap.at(6); ExpectEq(node6.blockBarrier.frontBarriers.size() == 1, true); - ExpectEq(node6.blockBarrier.rearBarriers.size() == 1, true); + // resource later used by raster pass, so that layout can be transferred automatically. + ExpectEq(node6.blockBarrier.rearBarriers.empty(), true); ExpectEq(node6.subpassBarriers.empty(), true); - auto iter8in6 = findBarrierByResID(node6.blockBarrier.rearBarriers, 8); - const auto& res8in6 = (*iter8in6); - ExpectEq(res8in6.type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(res8in6.resourceID == 8, true); - ExpectEq(res8in6.beginStatus.vertID == 6, true); - ExpectEq(res8in6.endStatus.vertID == 13, true); - ExpectEq(res8in6.beginStatus.passType == PassType::COPY, true); - ExpectEq(res8in6.endStatus.passType == PassType::RASTER, true); - ExpectEq(res8in6.beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); - ExpectEq(res8in6.endStatus.access == MemoryAccessBit::READ_ONLY, true); - // node7 const auto& node7 = barrierMap.at(7); - ExpectEq(node7.blockBarrier.frontBarriers.size() == 1, true); - ExpectEq(node7.blockBarrier.rearBarriers.empty(), false); + // undefined layout already in initial layout + ExpectEq(node7.blockBarrier.frontBarriers.empty(), true); + ExpectEq(node7.blockBarrier.rearBarriers.empty(), true); ExpectEq(node7.subpassBarriers.empty(), true); - auto iter9in7 = findBarrierByResID(node7.blockBarrier.rearBarriers, 9); - const auto& res9in7 = (*iter9in7); - ExpectEq(res9in7.type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(res9in7.resourceID == 9, true); - ExpectEq(res9in7.beginStatus.vertID == 7, true); - ExpectEq(res9in7.endStatus.vertID == 10, true); - ExpectEq(res9in7.beginStatus.passType == PassType::COMPUTE, true); - ExpectEq(res9in7.endStatus.passType == PassType::RASTER, true); + ExpectEq(node7.blockBarrier.rearBarriers.size(), 0); //node8: almost the same as node7 //node9: almost the same as node8 @@ -240,43 +217,10 @@ TEST(complicatedBarrierTest, test12) { //node13 const auto& node13 = barrierMap.at(13); - ExpectEq(node13.blockBarrier.frontBarriers.size() == 3, true); - ExpectEq(node13.blockBarrier.rearBarriers.size() == 1, true); + ExpectEq(node13.blockBarrier.frontBarriers.size(), 0); + ExpectEq(node13.blockBarrier.rearBarriers.size(), 0); ExpectEq(node13.subpassBarriers.empty(), true); - auto iter8in13 = findBarrierByResID(node13.blockBarrier.frontBarriers, 8); - const auto& res8in13 = (*iter8in13); - ExpectEq(res8in13.type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res8in13.resourceID == 8, true); - ExpectEq(res8in13.beginStatus.vertID == 6, true); - ExpectEq(res8in13.beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); - ExpectEq(res8in13.beginStatus.passType == PassType::COPY, true); - ExpectEq(res8in13.endStatus.vertID == 13, true); - ExpectEq(res8in13.endStatus.access == MemoryAccessBit::READ_ONLY, true); - ExpectEq(res8in13.endStatus.passType == PassType::RASTER, true); - - auto iter10in13 = findBarrierByResID(node13.blockBarrier.frontBarriers, 10); - const auto& res10in13 = (*iter10in13); - ExpectEq(res10in13.type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res10in13.resourceID == 10, true); - ExpectEq(res10in13.beginStatus.vertID == 10, true); - ExpectEq(res10in13.beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); - ExpectEq(res10in13.beginStatus.passType == PassType::RASTER, true); - ExpectEq(res10in13.endStatus.vertID == 13, true); - ExpectEq(res10in13.endStatus.access == MemoryAccessBit::READ_ONLY, true); - ExpectEq(res10in13.endStatus.passType == PassType::RASTER, true); - - auto iter11in13 = findBarrierByResID(node13.blockBarrier.rearBarriers, 11); - const auto& res11in13 = (*iter11in13); - ExpectEq(res11in13.type == cc::gfx::BarrierType::FULL, true); - ExpectEq(res11in13.resourceID == 11, true); - ExpectEq(res11in13.beginStatus.vertID == 13, true); - ExpectEq(res11in13.beginStatus.access == MemoryAccessBit::WRITE_ONLY, true); - ExpectEq(res11in13.beginStatus.passType == PassType::RASTER, true); - ExpectEq(res11in13.endStatus.vertID == 13, true); - ExpectEq(res11in13.endStatus.access == MemoryAccessBit::READ_ONLY, true); - ExpectEq(res11in13.endStatus.passType == PassType::RASTER, true); - //node14: almost the same as 13 //node15: ditto diff --git a/native/tests/unit-test/src/simple_barrier_test.cpp b/native/tests/unit-test/src/simple_barrier_test.cpp index 31e5913a3f6..d6c7dc7b5fc 100644 --- a/native/tests/unit-test/src/simple_barrier_test.cpp +++ b/native/tests/unit-test/src/simple_barrier_test.cpp @@ -70,7 +70,7 @@ TEST(barrierTest, test10) { //// 2nd node const auto& node2 = barrierMap.at(2); - ExpectEq(node2.blockBarrier.frontBarriers.size() == 1, true); + ExpectEq(node2.blockBarrier.frontBarriers.size(), 0); ExpectEq(node2.blockBarrier.rearBarriers.size() == 1, true); const auto& node2RearBarrier0 = node2.blockBarrier.rearBarriers.back(); diff --git a/native/tests/unit-test/src/simple_closed_barrier_test.cpp b/native/tests/unit-test/src/simple_closed_barrier_test.cpp index e09d214f3b1..6cfbcc275e2 100644 --- a/native/tests/unit-test/src/simple_closed_barrier_test.cpp +++ b/native/tests/unit-test/src/simple_closed_barrier_test.cpp @@ -52,119 +52,123 @@ TEST(simpleClosedBarrierTest, test11) { // 1st node const auto& node1 = barrierMap.at(1); - ExpectEq(node1.blockBarrier.frontBarriers.size() == 2, true); - ExpectEq(node1.blockBarrier.rearBarriers.size() == 2, true); + ExpectEq(node1.blockBarrier.frontBarriers.size(), 0); + ExpectEq(node1.blockBarrier.rearBarriers.size(), 0); ExpectEq(node1.subpassBarriers.empty(), true); - ExpectEq(node1.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node1.blockBarrier.rearBarriers[0].endStatus.vertID == 1, true); - ExpectEq(node1.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(node1.blockBarrier.rearBarriers[1].endStatus.vertID == 3, true); + // transitioned by renderpass info + //ExpectEq(node1.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node1.blockBarrier.rearBarriers[0].endStatus.vertID == 1, true); + //ExpectEq(node1.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); + //ExpectEq(node1.blockBarrier.rearBarriers[1].endStatus.vertID == 3, true); const auto& node2 = barrierMap.at(2); - ExpectEq(node2.blockBarrier.frontBarriers.size() == 2, true); - ExpectEq(node2.blockBarrier.rearBarriers.size() == 2, true); + ExpectEq(node2.blockBarrier.frontBarriers.size(), 0); + ExpectEq(node2.blockBarrier.rearBarriers.size(), 0); ExpectEq(node2.subpassBarriers.empty(), true); - // res3 - ExpectEq(node2.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(node2.blockBarrier.rearBarriers[1].beginStatus.vertID == 2, true); - ExpectEq(node2.blockBarrier.rearBarriers[1].endStatus.vertID == 5, true); - // res2 - ExpectEq(node2.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(node2.blockBarrier.rearBarriers[0].beginStatus.vertID == 2, true); - ExpectEq(node2.blockBarrier.rearBarriers[0].endStatus.vertID == 4, true); - - const auto& node3 = barrierMap.at(3); - ExpectEq(node3.blockBarrier.frontBarriers.size() == 3, true); - ExpectEq(node3.blockBarrier.rearBarriers.size() == 2, true); - ExpectEq(node3.subpassBarriers.empty(), true); - - const auto& res1Index = std::find_if(node3.blockBarrier.frontBarriers.begin(), node3.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 1; }); - ExpectEq(res1Index != node3.blockBarrier.frontBarriers.end(), true); - ExpectEq(res1Index->type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res1Index->beginStatus.vertID == 1, true); - ExpectEq(res1Index->endStatus.vertID == 3, true); - // res 5 - ExpectEq(node3.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node3.blockBarrier.rearBarriers[0].beginStatus.vertID == 3, true); - ExpectEq(node3.blockBarrier.rearBarriers[0].endStatus.vertID == 3, true); - // res 4 - ExpectEq(node3.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(node3.blockBarrier.rearBarriers[1].beginStatus.vertID == 3, true); - ExpectEq(node3.blockBarrier.rearBarriers[1].endStatus.vertID == 5, true); - - const auto& node4 = barrierMap.at(4); - ExpectEq(node4.blockBarrier.frontBarriers.size() == 2, true); - ExpectEq(node4.blockBarrier.rearBarriers.size() == 1, true); - ExpectEq(node4.subpassBarriers.empty(), true); - - const auto& res3Index = std::find_if(node4.blockBarrier.frontBarriers.begin(), node4.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 3; }); - ExpectEq(res3Index != node4.blockBarrier.frontBarriers.end(), true); - ExpectEq(res3Index->type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res3Index->beginStatus.vertID == 2, true); - ExpectEq(res3Index->endStatus.vertID == 4, true); - - ExpectEq(node4.blockBarrier.rearBarriers[0].resourceID == 6, true); - ExpectEq(node4.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node4.blockBarrier.rearBarriers[0].beginStatus.vertID == 4, true); - ExpectEq(node4.blockBarrier.rearBarriers[0].endStatus.vertID == 4, true); - - const auto& node5 = barrierMap.at(5); - ExpectEq(node5.blockBarrier.frontBarriers.size() == 3, true); - ExpectEq(node5.blockBarrier.rearBarriers.size() == 1, true); - ExpectEq(node5.subpassBarriers.empty(), true); - - const auto& res2Index = std::find_if(node5.blockBarrier.frontBarriers.begin(), node5.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 2; }); - ExpectEq(res2Index != node5.blockBarrier.frontBarriers.end(), true); - ExpectEq(res2Index->type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res2Index->beginStatus.vertID == 2, true); - ExpectEq(res2Index->endStatus.vertID == 5, true); - const auto& res4Index = std::find_if(node5.blockBarrier.frontBarriers.begin(), node5.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 4; }); - ExpectEq(res4Index != node5.blockBarrier.frontBarriers.end(), true); - ExpectEq(res4Index->type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(res4Index->beginStatus.vertID == 3, true); - ExpectEq(res4Index->endStatus.vertID == 5, true); - - ExpectEq(node5.blockBarrier.rearBarriers[0].resourceID == 7, true); - ExpectEq(node5.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); - ExpectEq(node5.blockBarrier.rearBarriers[0].beginStatus.vertID == 5, true); - ExpectEq(node5.blockBarrier.rearBarriers[0].endStatus.vertID == 8, true); - - const auto& node6 = barrierMap.at(6); - ExpectEq(node6.blockBarrier.frontBarriers.size() == 1, true); - ExpectEq(node6.blockBarrier.rearBarriers.size() == 1, true); - ExpectEq(node6.subpassBarriers.empty(), true); - - ExpectEq(node6.blockBarrier.rearBarriers[0].resourceID == 8, true); - ExpectEq(node6.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node6.blockBarrier.rearBarriers[0].beginStatus.vertID == 6, true); - ExpectEq(node6.blockBarrier.rearBarriers[0].endStatus.vertID == 6, true); - - const auto& node7 = barrierMap.at(7); - ExpectEq(node7.subpassBarriers.empty(), true); - ExpectEq(node7.blockBarrier.frontBarriers.size() == 1, true); - ExpectEq(node7.blockBarrier.rearBarriers.size() == 1, true); - - ExpectEq(node7.blockBarrier.rearBarriers[0].resourceID == 9, true); - ExpectEq(node7.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node7.blockBarrier.rearBarriers[0].beginStatus.vertID == 7, true); - ExpectEq(node7.blockBarrier.rearBarriers[0].endStatus.vertID == 7, true); - - const auto& node8 = barrierMap.at(8); - ExpectEq(node8.subpassBarriers.empty(), true); - ExpectEq(node8.blockBarrier.frontBarriers.empty(), false); // size == 1 - ExpectEq(node8.blockBarrier.rearBarriers.size() == 1, true); - - ExpectEq(node8.blockBarrier.frontBarriers[1].resourceID == 7, true); - ExpectEq(node8.blockBarrier.frontBarriers[1].type == cc::gfx::BarrierType::SPLIT_END, true); - ExpectEq(node8.blockBarrier.frontBarriers[1].beginStatus.vertID == 5, true); - ExpectEq(node8.blockBarrier.frontBarriers[1].endStatus.vertID == 8, true); - - ExpectEq(node8.blockBarrier.rearBarriers[0].resourceID == 22, true); - ExpectEq(node8.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); - ExpectEq(node8.blockBarrier.rearBarriers[0].beginStatus.vertID == 8, true); - ExpectEq(node8.blockBarrier.rearBarriers[0].endStatus.vertID == 0xFFFFFFFF, true); + // ditto + //// res3 + //ExpectEq(node2.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); + //ExpectEq(node2.blockBarrier.rearBarriers[1].beginStatus.vertID == 2, true); + //ExpectEq(node2.blockBarrier.rearBarriers[1].endStatus.vertID == 5, true); + //// res2 + //ExpectEq(node2.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); + //ExpectEq(node2.blockBarrier.rearBarriers[0].beginStatus.vertID == 2, true); + //ExpectEq(node2.blockBarrier.rearBarriers[0].endStatus.vertID == 4, true); + + //const auto& node3 = barrierMap.at(3); + //ExpectEq(node3.blockBarrier.frontBarriers.size() == 3, true); + //ExpectEq(node3.blockBarrier.rearBarriers.size() == 2, true); + //ExpectEq(node3.subpassBarriers.empty(), true); + + //const auto& res1Index = std::find_if(node3.blockBarrier.frontBarriers.begin(), node3.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 1; }); + //ExpectEq(res1Index != node3.blockBarrier.frontBarriers.end(), true); + //ExpectEq(res1Index->type == cc::gfx::BarrierType::SPLIT_END, true); + //ExpectEq(res1Index->beginStatus.vertID == 1, true); + //ExpectEq(res1Index->endStatus.vertID == 3, true); + //// res 5 + //ExpectEq(node3.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node3.blockBarrier.rearBarriers[0].beginStatus.vertID == 3, true); + //ExpectEq(node3.blockBarrier.rearBarriers[0].endStatus.vertID == 3, true); + //// res 4 + //ExpectEq(node3.blockBarrier.rearBarriers[1].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); + //ExpectEq(node3.blockBarrier.rearBarriers[1].beginStatus.vertID == 3, true); + //ExpectEq(node3.blockBarrier.rearBarriers[1].endStatus.vertID == 5, true); + + //const auto& node4 = barrierMap.at(4); + //ExpectEq(node4.blockBarrier.frontBarriers.size() == 2, true); + //ExpectEq(node4.blockBarrier.rearBarriers.size() == 1, true); + //ExpectEq(node4.subpassBarriers.empty(), true); + + //const auto& res3Index = std::find_if(node4.blockBarrier.frontBarriers.begin(), node4.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 3; }); + //ExpectEq(res3Index != node4.blockBarrier.frontBarriers.end(), true); + //ExpectEq(res3Index->type == cc::gfx::BarrierType::SPLIT_END, true); + //ExpectEq(res3Index->beginStatus.vertID == 2, true); + //ExpectEq(res3Index->endStatus.vertID == 4, true); + + //ExpectEq(node4.blockBarrier.rearBarriers[0].resourceID == 6, true); + //ExpectEq(node4.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node4.blockBarrier.rearBarriers[0].beginStatus.vertID == 4, true); + //ExpectEq(node4.blockBarrier.rearBarriers[0].endStatus.vertID == 4, true); + + //const auto& node5 = barrierMap.at(5); + //ExpectEq(node5.blockBarrier.frontBarriers.size() == 3, true); + //ExpectEq(node5.blockBarrier.rearBarriers.size() == 1, true); + //ExpectEq(node5.subpassBarriers.empty(), true); + + //const auto& res2Index = std::find_if(node5.blockBarrier.frontBarriers.begin(), node5.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 2; }); + //ExpectEq(res2Index != node5.blockBarrier.frontBarriers.end(), true); + //ExpectEq(res2Index->type == cc::gfx::BarrierType::SPLIT_END, true); + //ExpectEq(res2Index->beginStatus.vertID == 2, true); + //ExpectEq(res2Index->endStatus.vertID == 5, true); + //const auto& res4Index = std::find_if(node5.blockBarrier.frontBarriers.begin(), node5.blockBarrier.frontBarriers.end(), [](const Barrier& barrier) { return barrier.resourceID == 4; }); + //ExpectEq(res4Index != node5.blockBarrier.frontBarriers.end(), true); + //ExpectEq(res4Index->type == cc::gfx::BarrierType::SPLIT_END, true); + //ExpectEq(res4Index->beginStatus.vertID == 3, true); + //ExpectEq(res4Index->endStatus.vertID == 5, true); + + //ExpectEq(node5.blockBarrier.rearBarriers[0].resourceID == 7, true); + //ExpectEq(node5.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::SPLIT_BEGIN, true); + //ExpectEq(node5.blockBarrier.rearBarriers[0].beginStatus.vertID == 5, true); + //ExpectEq(node5.blockBarrier.rearBarriers[0].endStatus.vertID == 8, true); + + //const auto& node6 = barrierMap.at(6); + //ExpectEq(node6.blockBarrier.frontBarriers.size() == 1, true); + //ExpectEq(node6.blockBarrier.rearBarriers.size() == 1, true); + //ExpectEq(node6.subpassBarriers.empty(), true); + + //ExpectEq(node6.blockBarrier.rearBarriers[0].resourceID == 8, true); + //ExpectEq(node6.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node6.blockBarrier.rearBarriers[0].beginStatus.vertID == 6, true); + //ExpectEq(node6.blockBarrier.rearBarriers[0].endStatus.vertID == 6, true); + + //const auto& node7 = barrierMap.at(7); + //ExpectEq(node7.subpassBarriers.empty(), true); + //ExpectEq(node7.blockBarrier.frontBarriers.size() == 1, true); + //ExpectEq(node7.blockBarrier.rearBarriers.size() == 1, true); + + //ExpectEq(node7.blockBarrier.rearBarriers[0].resourceID == 9, true); + //ExpectEq(node7.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node7.blockBarrier.rearBarriers[0].beginStatus.vertID == 7, true); + //ExpectEq(node7.blockBarrier.rearBarriers[0].endStatus.vertID == 7, true); + + //const auto& node8 = barrierMap.at(8); + //ExpectEq(node8.subpassBarriers.empty(), true); + //ExpectEq(node8.blockBarrier.frontBarriers.empty(), false); // size == 1 + //ExpectEq(node8.blockBarrier.rearBarriers.size() == 1, true); + + //ExpectEq(node8.blockBarrier.frontBarriers[1].resourceID == 7, true); + //ExpectEq(node8.blockBarrier.frontBarriers[1].type == cc::gfx::BarrierType::SPLIT_END, true); + //ExpectEq(node8.blockBarrier.frontBarriers[1].beginStatus.vertID == 5, true); + //ExpectEq(node8.blockBarrier.frontBarriers[1].endStatus.vertID == 8, true); + + //ExpectEq(node8.blockBarrier.rearBarriers[0].resourceID == 22, true); + //ExpectEq(node8.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); + //ExpectEq(node8.blockBarrier.rearBarriers[0].beginStatus.vertID == 8, true); + //ExpectEq(node8.blockBarrier.rearBarriers[0].endStatus.vertID == 0xFFFFFFFF, true); + + // TODO: validate renderpassInfo instead const auto& node9 = barrierMap.at(9); ExpectEq(node9.subpassBarriers.empty(), true); From ec2b849463bf1fbdf0eb2d067a110a8b2f02d4f4 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 16 Jun 2023 14:54:54 +0800 Subject: [PATCH 11/57] fix vk csm --- cocos/rendering/custom/define.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index a17e0c5c6e5..04495c513e3 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -167,7 +167,7 @@ export function getRenderArea (camera: Camera, width: number, height: number, li } else { const screenSpaceSignY = cclegacy.director.root.device.capabilities.screenSpaceSignY; out.x = level % 2 * 0.5 * w; - if (screenSpaceSignY) { + if (screenSpaceSignY > 0) { out.y = (1 - Math.floor(level / 2)) * 0.5 * h; } else { out.y = Math.floor(level / 2) * 0.5 * h; From 365d12762d3aa7c607b21bdd15660fd27f22ce5d Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 16 Jun 2023 15:38:52 +0800 Subject: [PATCH 12/57] update custom pipeline effect import error log --- cocos/render-scene/core/pass.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 475454605a3..2930c23d519 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -491,7 +491,7 @@ export class Pass { this._device, this._phaseID, this._programName, this._defines, ); if (!program) { - console.warn(`create shader ${this._programName} failed`); + console.warn(`create shader ${this._programName} failed, please restart editor`); return false; } this._shader = program.shader; @@ -584,11 +584,11 @@ export class Pass { } } if (this._passID === r.INVALID_ID) { - console.error(`Invalid render pass, program: ${info.program}`); + console.error(`Invalid render pass, program: ${info.program}, please restart editor`); return; } if (this._phaseID === r.INVALID_ID) { - console.error(`Invalid render phase, program: ${info.program}`); + console.error(`Invalid render phase, program: ${info.program}, please restart editor`); return; } } From 69d90a125f952c17d8e92fe1ee3a1f3ee91640e2 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 16 Jun 2023 16:02:09 +0800 Subject: [PATCH 13/57] update error map --- EngineErrorMap.md | 28 ++++++++++++++++++++++++++++ cocos/render-scene/core/pass.ts | 16 ++++++++-------- cocos/rendering/custom/define.ts | 3 --- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/EngineErrorMap.md b/EngineErrorMap.md index 8385a84bae7..214e156a5c8 100644 --- a/EngineErrorMap.md +++ b/EngineErrorMap.md @@ -3267,6 +3267,34 @@ The font size is too big to be fitted into texture atlas. Please switch to other The asset %s has been destroyed! +### 12102 + +Base pass cannot override states, please use pass instance instead. + +### 12103 + +Custom pipeline create shader %s failed. Please restart editor. + +### 12104 + +Create shader %s failed. + +### 12105 + +Pass resources incomplete. + +### 12106 + +Cannot patch non-builtin macros. + +### 12107 + +Custom pipeline invalid render pass, program: %s. Please restart editor. + +### 12108 + +Custom pipeline invalid render phase, program: %s. Please restart editor. + ### 13100 Incorrect CCON magic. diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 2930c23d519..9e7b2565003 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -27,7 +27,7 @@ import { Root } from '../../root'; import { TextureBase } from '../../asset/assets/texture-base'; import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { getPhaseID } from '../../rendering/pass-phase'; -import { murmurhash2_32_gc, errorID, assertID, cclegacy } from '../../core'; +import { murmurhash2_32_gc, errorID, assertID, cclegacy, warnID } from '../../core'; import { BufferUsageBit, DynamicStateFlagBit, DynamicStateFlags, Feature, GetTypeSize, MemoryUsageBit, PrimitiveMode, Type, Color, BlendState, BlendTarget, Buffer, BufferInfo, BufferViewInfo, DepthStencilState, DescriptorSet, DescriptorSetInfo, DescriptorSetLayout, Device, RasterizerState, Sampler, Texture, Shader, PipelineLayout, deviceManager, UniformBlock, @@ -347,7 +347,7 @@ export class Pass { * @param value The override pipeline state info */ public overridePipelineStates (original: EffectAsset.IPassInfo, overrides: PassOverrides): void { - console.warn('base pass cannot override states, please use pass instance instead.'); + warnID(12102); } /** @@ -491,7 +491,7 @@ export class Pass { this._device, this._phaseID, this._programName, this._defines, ); if (!program) { - console.warn(`create shader ${this._programName} failed, please restart editor`); + warnID(12103, this._programName); return false; } this._shader = program.shader; @@ -499,7 +499,7 @@ export class Pass { } else { const shader = programLib.getGFXShader(this._device, this._programName, this._defines, pipeline); if (!shader) { - console.warn(`create shader ${this._programName} failed`); + warnID(12104, this._programName); return false; } this._shader = shader; @@ -517,7 +517,7 @@ export class Pass { */ public getShaderVariant (patches: Readonly = null): Shader | null { if (!this._shader && !this.tryCompile()) { - console.warn('pass resources incomplete'); + warnID(12105); return null; } @@ -528,7 +528,7 @@ export class Pass { if (EDITOR) { for (let i = 0; i < patches.length; i++) { if (!patches[i].name.startsWith('CC_')) { - console.warn('cannot patch non-builtin macros'); + warnID(12106); return null; } } @@ -584,11 +584,11 @@ export class Pass { } } if (this._passID === r.INVALID_ID) { - console.error(`Invalid render pass, program: ${info.program}, please restart editor`); + errorID(12107, info.program); return; } if (this._phaseID === r.INVALID_ID) { - console.error(`Invalid render phase, program: ${info.program}, please restart editor`); + errorID(12108, info.program); return; } } diff --git a/cocos/rendering/custom/define.ts b/cocos/rendering/custom/define.ts index 4d39bcf6802..35cb21a365d 100644 --- a/cocos/rendering/custom/define.ts +++ b/cocos/rendering/custom/define.ts @@ -1697,9 +1697,6 @@ class HBAOParams { this.randomTexture.setMipFilter(Texture2D.Filter.NONE); this.randomTexture.setWrapMode(Texture2D.WrapMode.REPEAT, Texture2D.WrapMode.REPEAT, Texture2D.WrapMode.REPEAT); this.randomTexture.image = image; - if (!this.randomTexture.getGFXTexture()) { - console.warn('Unexpected: failed to create ao texture?'); - } this.hbaoMaterial.setProperty('RandomTex', this.randomTexture, 0); } From dc2f864b2199db766b73b41910fd1f64035b6b38 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 16 Jun 2023 16:58:07 +0800 Subject: [PATCH 14/57] fix typo --- editor/assets/effects/builtin-terrain.effect | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/assets/effects/builtin-terrain.effect b/editor/assets/effects/builtin-terrain.effect index 82df4878104..f3c3faa528e 100644 --- a/editor/assets/effects/builtin-terrain.effect +++ b/editor/assets/effects/builtin-terrain.effect @@ -49,7 +49,7 @@ CCEffect %{ propertyIndex: 0 - vert: terrain-vs frag: terrain-fs - phase: deferred-forwar + phase: deferred-forward propertyIndex: 0 }% From 49fc0e154e729befeef9ddabe561a4e06430ac7c Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 16 Jun 2023 19:07:32 +0800 Subject: [PATCH 15/57] Forward defaulted to PostProcessBuilder --- cocos/rendering/custom/index.jsb.ts | 3 ++- cocos/rendering/custom/index.ts | 3 ++- cocos/rendering/custom/pipeline.ts | 9 -------- cocos/rendering/custom/web-pipeline.ts | 3 --- cocos/rendering/post-process/index.ts | 4 ++++ .../post-process/passes/blit-screen-pass.ts | 5 ++-- .../post-process/passes/bloom-pass.ts | 4 ++-- .../post-process/passes/color-grading-pass.ts | 2 +- .../post-process/passes/forward-pass.ts | 6 ++--- .../passes/forward-transparency-pass.ts | 2 +- .../forward-transparency-simple-pass.ts | 5 +--- .../rendering/post-process/passes/fsr-pass.ts | 4 ++-- .../post-process/passes/fxaa-pass.ts | 4 ++-- .../post-process/passes/hbao-pass.ts | 2 +- .../post-process/passes/skin-pass.ts | 4 ++-- .../rendering/post-process/passes/taa-pass.ts | 3 ++- .../post-process/passes/tone-mapping-pass.ts | 2 +- .../post-process/post-process-builder.ts | 3 --- native/CMakeLists.txt | 23 +++++++++++++++---- .../pipeline/custom/NativePipeline.cpp | 5 ---- .../pipeline/custom/NativePipelineTypes.h | 1 - .../pipeline/custom/RenderInterfaceTypes.h | 4 ---- 22 files changed, 45 insertions(+), 56 deletions(-) diff --git a/cocos/rendering/custom/index.jsb.ts b/cocos/rendering/custom/index.jsb.ts index 74330f71675..ce9a0e531f6 100644 --- a/cocos/rendering/custom/index.jsb.ts +++ b/cocos/rendering/custom/index.jsb.ts @@ -28,6 +28,7 @@ import { Pipeline, PipelineBuilder, RenderingModule } from './pipeline'; import { DeferredPipelineBuilder, ForwardPipelineBuilder } from './builtin-pipelines'; import { CustomPipelineBuilder, TestPipelineBuilder } from './custom-pipeline'; import { Device } from '../../gfx'; +import { PostProcessBuilder } from '../post-process/post-process-builder'; export * from './types'; export * from './pipeline'; @@ -65,7 +66,7 @@ export function getCustomPipeline (name: string): PipelineBuilder { } function addCustomBuiltinPipelines (map: Map) { - map.set('Forward', new ForwardPipelineBuilder()); + map.set('Forward', new PostProcessBuilder()); map.set('Deferred', new DeferredPipelineBuilder()); map.set('Deprecated', new CustomPipelineBuilder()); } diff --git a/cocos/rendering/custom/index.ts b/cocos/rendering/custom/index.ts index fc86fff574f..2a21ea3b31e 100644 --- a/cocos/rendering/custom/index.ts +++ b/cocos/rendering/custom/index.ts @@ -34,6 +34,7 @@ import { WebProgramLibrary } from './web-program-library'; import { Device } from '../../gfx'; import { initializeLayoutGraphData, terminateLayoutGraphData, getCustomPassID, getCustomPhaseID } from './layout-graph-utils'; import { ProgramLibrary } from './private'; +import { PostProcessBuilder } from '../post-process/post-process-builder'; let _pipeline: WebPipeline | null = null; @@ -77,7 +78,7 @@ export function getCustomPipeline (name: string): PipelineBuilder { } function addCustomBuiltinPipelines (map: Map) { - map.set('Forward', new ForwardPipelineBuilder()); + map.set('Forward', new PostProcessBuilder()); map.set('Deferred', new DeferredPipelineBuilder()); map.set('Deprecated', new CustomPipelineBuilder()); } diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index a705a5c139f..582546ff523 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -169,15 +169,6 @@ export interface BasicPipeline extends PipelineRuntime { beginSetup (): void; endSetup (): void; containsResource (name: string): boolean; - /** - * @deprecated method will be removed in 3.9.0 - */ - addRenderTexture ( - name: string, - format: Format, - width: number, - height: number, - renderWindow: RenderWindow): number; addRenderWindow ( name: string, format: Format, diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 58c24a9a5b2..3f0efe34390 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1281,9 +1281,6 @@ export class WebPipeline implements BasicPipeline { addCustomTexture (name: string, info: TextureInfo, type: string): number { throw new Error('Method not implemented.'); } - addRenderTexture (name: string, format: Format, width: number, height: number, renderWindow: RenderWindow): number { - return this.addRenderWindow(name, format, width, height, renderWindow); - } addRenderWindow (name: string, format: Format, width: number, height: number, renderWindow: RenderWindow): number { const desc = new ResourceDesc(); desc.dimension = ResourceDimension.TEXTURE2D; diff --git a/cocos/rendering/post-process/index.ts b/cocos/rendering/post-process/index.ts index d2b3f1bb73d..255d537bd86 100644 --- a/cocos/rendering/post-process/index.ts +++ b/cocos/rendering/post-process/index.ts @@ -1,5 +1,9 @@ +import { setCustomPipeline } from '../custom'; +import { PostProcessBuilder } from './post-process-builder'; import './utils/pass-context'; export * from './components'; export * from './passes'; export * from './post-process-builder'; + +setCustomPipeline('Custom', new PostProcessBuilder()); diff --git a/cocos/rendering/post-process/passes/blit-screen-pass.ts b/cocos/rendering/post-process/passes/blit-screen-pass.ts index fe9c53e1651..5be1e707c69 100644 --- a/cocos/rendering/post-process/passes/blit-screen-pass.ts +++ b/cocos/rendering/post-process/passes/blit-screen-pass.ts @@ -1,9 +1,8 @@ import { EDITOR } from 'internal:constants'; -import { Vec4 } from '../../../core'; -import { ClearFlagBit, Format } from '../../../gfx'; +import { Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; import { getSetting, SettingPass } from './setting-pass'; diff --git a/cocos/rendering/post-process/passes/bloom-pass.ts b/cocos/rendering/post-process/passes/bloom-pass.ts index c47ad409832..d3bb3a70c59 100644 --- a/cocos/rendering/post-process/passes/bloom-pass.ts +++ b/cocos/rendering/post-process/passes/bloom-pass.ts @@ -1,7 +1,7 @@ import { Vec4 } from '../../../core'; -import { ClearFlagBit, Format } from '../../../gfx'; +import { Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/color-grading-pass.ts b/cocos/rendering/post-process/passes/color-grading-pass.ts index fa42412a1c7..7c72546ac3d 100644 --- a/cocos/rendering/post-process/passes/color-grading-pass.ts +++ b/cocos/rendering/post-process/passes/color-grading-pass.ts @@ -1,7 +1,7 @@ import { Vec4 } from '../../../core'; import { ClearFlagBit, Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/forward-pass.ts b/cocos/rendering/post-process/passes/forward-pass.ts index b26b0758af8..b2a1f7594dc 100644 --- a/cocos/rendering/post-process/passes/forward-pass.ts +++ b/cocos/rendering/post-process/passes/forward-pass.ts @@ -1,10 +1,8 @@ -import { EDITOR } from 'internal:constants'; import { Vec4 } from '../../../core'; -import { director } from '../../../game'; import { ClearFlagBit, Format } from '../../../gfx'; -import { Camera, CameraUsage } from '../../../render-scene/scene'; -import { AccessType, LightInfo, QueueHint, ResourceResidency, SceneFlags } from '../../custom'; +import { Camera } from '../../../render-scene/scene'; +import { LightInfo, QueueHint, SceneFlags } from '../../custom/types'; import { getCameraUniqueID } from '../../custom/define'; import { Pipeline } from '../../custom/pipeline'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/forward-transparency-pass.ts b/cocos/rendering/post-process/passes/forward-transparency-pass.ts index 64c4e375914..8761a442a41 100644 --- a/cocos/rendering/post-process/passes/forward-transparency-pass.ts +++ b/cocos/rendering/post-process/passes/forward-transparency-pass.ts @@ -24,7 +24,7 @@ import { ClearFlagBit, Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { LightInfo, QueueHint, SceneFlags } from '../../custom'; +import { LightInfo, QueueHint, SceneFlags } from '../../custom/types'; import { getCameraUniqueID } from '../../custom/define'; import { Pipeline } from '../../custom/pipeline'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/forward-transparency-simple-pass.ts b/cocos/rendering/post-process/passes/forward-transparency-simple-pass.ts index ae4dce7500d..aa20020d5d4 100644 --- a/cocos/rendering/post-process/passes/forward-transparency-simple-pass.ts +++ b/cocos/rendering/post-process/passes/forward-transparency-simple-pass.ts @@ -22,15 +22,12 @@ THE SOFTWARE. */ -import { ClearFlagBit, Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { LightInfo, QueueHint, SceneFlags } from '../../custom'; -import { getCameraUniqueID } from '../../custom/define'; +import { LightInfo, QueueHint, SceneFlags } from '../../custom/types'; import { Pipeline } from '../../custom/pipeline'; import { passContext } from '../utils/pass-context'; import { BasePass } from './base-pass'; import { ForwardPass } from './forward-pass'; -import { ShadowPass } from './shadow-pass'; export class ForwardTransparencySimplePass extends BasePass { name = 'ForwardTransparencySimplePass'; diff --git a/cocos/rendering/post-process/passes/fsr-pass.ts b/cocos/rendering/post-process/passes/fsr-pass.ts index 223095ee0ec..38ce42f6cc1 100644 --- a/cocos/rendering/post-process/passes/fsr-pass.ts +++ b/cocos/rendering/post-process/passes/fsr-pass.ts @@ -1,8 +1,8 @@ import { EDITOR } from 'internal:constants'; import { Vec4 } from '../../../core'; -import { ClearFlagBit, Format } from '../../../gfx'; +import { Format } from '../../../gfx'; import { Camera, CameraUsage } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/fxaa-pass.ts b/cocos/rendering/post-process/passes/fxaa-pass.ts index ce0e1364ca5..64419cad668 100644 --- a/cocos/rendering/post-process/passes/fxaa-pass.ts +++ b/cocos/rendering/post-process/passes/fxaa-pass.ts @@ -1,7 +1,7 @@ import { Vec4 } from '../../../core'; -import { ClearFlagBit, Format } from '../../../gfx'; +import { Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/hbao-pass.ts b/cocos/rendering/post-process/passes/hbao-pass.ts index 0901ea27d0e..32c1593903b 100644 --- a/cocos/rendering/post-process/passes/hbao-pass.ts +++ b/cocos/rendering/post-process/passes/hbao-pass.ts @@ -25,7 +25,7 @@ import { EDITOR } from 'internal:constants'; import { cclegacy, toRadian, Vec2, Vec4, Vec3, v3 } from '../../../core'; import { Camera, CameraUsage } from '../../../render-scene/scene'; -import { Pipeline, QueueHint } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/skin-pass.ts b/cocos/rendering/post-process/passes/skin-pass.ts index 41ee7e02e0f..bd53f0f89e0 100644 --- a/cocos/rendering/post-process/passes/skin-pass.ts +++ b/cocos/rendering/post-process/passes/skin-pass.ts @@ -24,11 +24,11 @@ import { Vec4, Vec3, cclegacy, warnID } from '../../../core'; import { Camera } from '../../../render-scene/scene'; -import { BasicPipeline, LightInfo, PipelineRuntime, QueueHint, SceneFlags } from '../../custom'; +import { LightInfo, QueueHint, SceneFlags } from '../../custom/types'; +import { BasicPipeline, PipelineRuntime } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; import { ClearFlagBit, Format } from '../../../gfx'; -import { MeshRenderer } from '../../../3d/framework/mesh-renderer'; import { ShadowPass } from './shadow-pass'; import { Root } from '../../../root'; diff --git a/cocos/rendering/post-process/passes/taa-pass.ts b/cocos/rendering/post-process/passes/taa-pass.ts index 0b9451fd663..377637ef0f3 100644 --- a/cocos/rendering/post-process/passes/taa-pass.ts +++ b/cocos/rendering/post-process/passes/taa-pass.ts @@ -3,7 +3,8 @@ import { Mat4, Vec2, Vec4 } from '../../../core'; import { game } from '../../../game'; import { ClearFlagBit, Format } from '../../../gfx'; import { Camera, CameraUsage } from '../../../render-scene/scene'; -import { Pipeline, ResourceResidency } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; +import { ResourceResidency } from '../../custom/types'; import { getCameraUniqueID } from '../../custom/define'; import { TAA } from '../components/taa'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/passes/tone-mapping-pass.ts b/cocos/rendering/post-process/passes/tone-mapping-pass.ts index 47b02c07495..cedf55f1cb0 100644 --- a/cocos/rendering/post-process/passes/tone-mapping-pass.ts +++ b/cocos/rendering/post-process/passes/tone-mapping-pass.ts @@ -25,7 +25,7 @@ import { Vec4, cclegacy } from '../../../core'; import { ClearFlagBit, Format } from '../../../gfx'; import { Camera } from '../../../render-scene/scene'; -import { Pipeline } from '../../custom'; +import { Pipeline } from '../../custom/pipeline'; import { getCameraUniqueID } from '../../custom/define'; import { passContext } from '../utils/pass-context'; diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index a6eb69d3963..c2d50dd3280 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -17,7 +17,6 @@ import { ShadowPass } from './passes/shadow-pass'; import { HBAOPass } from './passes/hbao-pass'; import { PostProcess } from './components/post-process'; import { director } from '../../game'; -import { setCustomPipeline } from '../custom'; import { CameraComponent } from '../../misc'; import { BloomPass, ColorGradingPass, ForwardTransparencyPass, ForwardTransparencySimplePass, FxaaPass, SkinPass, ToneMappingPass } from './passes'; @@ -223,5 +222,3 @@ export class PostProcessBuilder implements PipelineBuilder { } } } - -setCustomPipeline('Custom', new PostProcessBuilder()); diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 9c1011fa979..fa79c11db62 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -1384,12 +1384,7 @@ cocos_source_files( cocos/renderer/pipeline/DebugView.h cocos/renderer/pipeline/helper/Utils.h cocos/renderer/pipeline/helper/Utils.cpp - cocos/renderer/pipeline/custom/BinaryArchive.h - cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp - cocos/renderer/pipeline/custom/details/SerializationUtils.h cocos/renderer/pipeline/custom/test/test.h - cocos/renderer/pipeline/custom/NativeDefaultScene.cpp - cocos/renderer/pipeline/custom/NativeResourceGraph.cpp cocos/renderer/pipeline/reflection-probe/ReflectionProbeFlow.cpp cocos/renderer/pipeline/reflection-probe/ReflectionProbeFlow.h cocos/renderer/pipeline/reflection-probe/ReflectionProbeStage.cpp @@ -1399,12 +1394,14 @@ cocos_source_files( cocos/renderer/pipeline/custom/ArchiveFwd.h cocos/renderer/pipeline/custom/ArchiveTypes.cpp cocos/renderer/pipeline/custom/ArchiveTypes.h + cocos/renderer/pipeline/custom/BinaryArchive.h cocos/renderer/pipeline/custom/CustomFwd.h cocos/renderer/pipeline/custom/CustomTypes.cpp cocos/renderer/pipeline/custom/CustomTypes.h cocos/renderer/pipeline/custom/FGDispatcherGraphs.h cocos/renderer/pipeline/custom/FGDispatcherTypes.cpp cocos/renderer/pipeline/custom/FGDispatcherTypes.h + cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp cocos/renderer/pipeline/custom/LayoutGraphFwd.h cocos/renderer/pipeline/custom/LayoutGraphGraphs.h cocos/renderer/pipeline/custom/LayoutGraphNames.h @@ -1413,6 +1410,7 @@ cocos_source_files( cocos/renderer/pipeline/custom/LayoutGraphTypes.h cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp cocos/renderer/pipeline/custom/LayoutGraphUtils.h + cocos/renderer/pipeline/custom/NativeDefaultScene.cpp cocos/renderer/pipeline/custom/NativeExecutor.cpp cocos/renderer/pipeline/custom/NativeFactory.cpp cocos/renderer/pipeline/custom/NativeFwd.h @@ -1426,6 +1424,7 @@ cocos_source_files( cocos/renderer/pipeline/custom/NativeRenderGraph.cpp cocos/renderer/pipeline/custom/NativeRenderQueue.cpp cocos/renderer/pipeline/custom/NativeRenderingModule.cpp + cocos/renderer/pipeline/custom/NativeResourceGraph.cpp cocos/renderer/pipeline/custom/NativeSceneCulling.cpp cocos/renderer/pipeline/custom/NativeTypes.cpp cocos/renderer/pipeline/custom/NativeTypes.h @@ -1449,6 +1448,20 @@ cocos_source_files( cocos/renderer/pipeline/custom/RenderInterfaceTypes.cpp cocos/renderer/pipeline/custom/RenderInterfaceTypes.h cocos/renderer/pipeline/custom/RenderingModule.h + cocos/renderer/pipeline/custom/details/DebugUtils.h + cocos/renderer/pipeline/custom/details/GraphImpl.h + cocos/renderer/pipeline/custom/details/GraphTypes.h + cocos/renderer/pipeline/custom/details/GraphView.h + cocos/renderer/pipeline/custom/details/GslUtils.h + cocos/renderer/pipeline/custom/details/JsbConversion.h + cocos/renderer/pipeline/custom/details/Map.h + cocos/renderer/pipeline/custom/details/Overload.h + cocos/renderer/pipeline/custom/details/PathUtils.h + cocos/renderer/pipeline/custom/details/Pmr.h + cocos/renderer/pipeline/custom/details/Range.h + cocos/renderer/pipeline/custom/details/SerializationUtils.h + cocos/renderer/pipeline/custom/details/Set.h + cocos/renderer/pipeline/custom/details/Utility.h ) if (USE_GEOMETRY_RENDERER) diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index badeedd1d8f..c29c794f708 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -109,11 +109,6 @@ bool NativePipeline::containsResource(const ccstd::string &name) const { return contains(name.c_str(), resourceGraph); } -// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -uint32_t NativePipeline::addRenderTexture(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) { - return addRenderWindow(name, format, width, height, renderWindow); -} - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) uint32_t NativePipeline::addRenderWindow(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) { ResourceDesc desc{}; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index b60700a6e0e..b2b8aa64065 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -1100,7 +1100,6 @@ class NativePipeline final : public Pipeline { void beginSetup() override; void endSetup() override; bool containsResource(const ccstd::string &name) const override; - uint32_t addRenderTexture(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) override; uint32_t addRenderWindow(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) override; void updateRenderWindow(const ccstd::string &name, scene::RenderWindow *renderWindow) override; uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) override; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 0c404938bbd..be9cfdd205f 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -280,10 +280,6 @@ class BasicPipeline : public PipelineRuntime { virtual void beginSetup() = 0; virtual void endSetup() = 0; virtual bool containsResource(const ccstd::string &name) const = 0; - /** - * @deprecated method will be removed in 3.9.0 - */ - virtual uint32_t addRenderTexture(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) = 0; virtual uint32_t addRenderWindow(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) = 0; virtual void updateRenderWindow(const ccstd::string &name, scene::RenderWindow *renderWindow) = 0; virtual uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; From e20a7c09432ca501d32949bae37a4a509c7dc14e Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Mon, 19 Jun 2023 10:18:16 +0800 Subject: [PATCH 16/57] fix lint --- cocos/rendering/post-process/passes/hbao-pass.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/cocos/rendering/post-process/passes/hbao-pass.ts b/cocos/rendering/post-process/passes/hbao-pass.ts index 32c1593903b..220fcd1c653 100644 --- a/cocos/rendering/post-process/passes/hbao-pass.ts +++ b/cocos/rendering/post-process/passes/hbao-pass.ts @@ -135,9 +135,6 @@ class HBAOParams { this.randomTexture.setMipFilter(Texture2D.Filter.NONE); this.randomTexture.setWrapMode(Texture2D.WrapMode.REPEAT, Texture2D.WrapMode.REPEAT, Texture2D.WrapMode.REPEAT); this.randomTexture.image = image; - if (!this.randomTexture.getGFXTexture()) { - console.warn('Unexpected: failed to create ao texture?'); - } } public update () { From 57d76c35863f60b23097a8d1d4f111c5944f9306 Mon Sep 17 00:00:00 2001 From: GengineJS <476393671@qq.com> Date: Tue, 20 Jun 2023 10:57:48 +0800 Subject: [PATCH 17/57] [Fixed] Fix the issue of transparent objects not being rendered in the Custom pipeline. (#143) --- cocos/rendering/custom/executor.ts | 2 ++ cocos/rendering/custom/web-pipeline.ts | 7 ++++++- cocos/rendering/post-process/post-process-builder.ts | 3 +-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index 15a3084e765..234d207085d 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -866,6 +866,8 @@ class DeviceRenderPass { } resetResource (id: number, pass: RasterPass) { this._rasterInfo.applyInfo(id, pass); + this._layoutName = context.renderGraph.getLayout(id); + this._passID = cclegacy.rendering.getPassID(this._layoutName); this._deviceQueues.length = 0; let framebuffer: Framebuffer | null = null; const colTextures: Texture[] = []; diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 3f0efe34390..57ba22fcd88 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -139,10 +139,15 @@ export class WebSetter { return layout.uniformBlocks.get(nameID); } - protected _getCurrDescriptorBlock (block: string) { + protected _getCurrDescSetLayoutData () { const nodeId = this._lg.locateChild(0xFFFFFFFF, this._currStage); const ppl = this._lg.getLayout(nodeId); const layout = ppl.descriptorSets.get(UpdateFrequency.PER_PASS)!.descriptorSetLayoutData; + return layout; + } + + protected _getCurrDescriptorBlock (block: string) { + const layout = this._getCurrDescSetLayoutData(); const nameID: number = this._lg.attributeIndex.get(block)!; for (const block of layout.descriptorBlocks) { for (let i = 0; i !== block.descriptors.length; ++i) { diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index c2d50dd3280..a7e37e4f1f3 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -43,9 +43,8 @@ export class PostProcessBuilder implements PipelineBuilder { // forward pipeline this.addPass(forward); - // TODO: The skin material currently conflicts with the TransparencyPass queue and is temporarily pre-rendered by TransparencyPass. - this.addPass(new ForwardTransparencyPass()); this.addPass(new SkinPass()); + this.addPass(new ForwardTransparencyPass()); // pipeline related this.addPass(new HBAOPass()); From 4449b83c6d78e6aa08912ed5fef6de54cee802ae Mon Sep 17 00:00:00 2001 From: GengineJS <476393671@qq.com> Date: Tue, 20 Jun 2023 13:17:36 +0800 Subject: [PATCH 18/57] [Add] Add logic to make the post-processing pipeline effective in the editor state. (#144) --- cocos/rendering/post-process/post-process-builder.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index a7e37e4f1f3..c517f5a5fdb 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -5,7 +5,7 @@ import { PipelineBuilder, Pipeline } from '../custom/pipeline'; import { passContext } from './utils/pass-context'; import { ForwardFinalPass } from './passes/forward-final-pass'; -import { buildReflectionProbePasss, getCameraUniqueID } from '../custom/define'; +import { buildForwardPass, buildReflectionProbePasss, getCameraUniqueID } from '../custom/define'; import { BasePass } from './passes/base-pass'; import { ForwardPass } from './passes/forward-pass'; @@ -156,6 +156,15 @@ export class PostProcessBuilder implements PipelineBuilder { if (!camera.scene) { continue; } + const isGameView = camera.cameraUsage === CameraUsage.GAME + || camera.cameraUsage === CameraUsage.GAME_VIEW; + if (!isGameView) { + // forward pass + buildForwardPass(camera, ppl, isGameView); + // reflection probe pass + buildReflectionProbePasss(camera, ppl); + continue; + } ppl.update(camera); if (i === (cameras.length - 1)) { passContext.isFinalCamera = true; From af68340957a55c0cf1c81cf5946eba0fe4fbc0b4 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 20 Jun 2023 15:19:25 +0800 Subject: [PATCH 19/57] Revert "[Add] Add logic to make the post-processing pipeline effective in the editor state. (#144)" This reverts commit 4449b83c6d78e6aa08912ed5fef6de54cee802ae. --- cocos/rendering/post-process/post-process-builder.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index c517f5a5fdb..a7e37e4f1f3 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -5,7 +5,7 @@ import { PipelineBuilder, Pipeline } from '../custom/pipeline'; import { passContext } from './utils/pass-context'; import { ForwardFinalPass } from './passes/forward-final-pass'; -import { buildForwardPass, buildReflectionProbePasss, getCameraUniqueID } from '../custom/define'; +import { buildReflectionProbePasss, getCameraUniqueID } from '../custom/define'; import { BasePass } from './passes/base-pass'; import { ForwardPass } from './passes/forward-pass'; @@ -156,15 +156,6 @@ export class PostProcessBuilder implements PipelineBuilder { if (!camera.scene) { continue; } - const isGameView = camera.cameraUsage === CameraUsage.GAME - || camera.cameraUsage === CameraUsage.GAME_VIEW; - if (!isGameView) { - // forward pass - buildForwardPass(camera, ppl, isGameView); - // reflection probe pass - buildReflectionProbePasss(camera, ppl); - continue; - } ppl.update(camera); if (i === (cameras.length - 1)) { passContext.isFinalCamera = true; From d164666cb0675955394ebb1442fabb3212be0914 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 20 Jun 2023 15:36:26 +0800 Subject: [PATCH 20/57] sync with 3.8.1 --- cocos/rendering/custom/layout-graph.ts | 74 +++++++++++++------------- cocos/rendering/custom/render-graph.ts | 12 ++--- cocos/rendering/custom/types.ts | 36 ++++++------- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/cocos/rendering/custom/layout-graph.ts b/cocos/rendering/custom/layout-graph.ts index 8d6ece7be93..9ec1346ce68 100644 --- a/cocos/rendering/custom/layout-graph.ts +++ b/cocos/rendering/custom/layout-graph.ts @@ -1067,7 +1067,7 @@ export class LayoutGraphData implements BidirectionalGraph getUpdate (v: number): UpdateFrequency { return this._updateFrequencies[v]; } - setUpdate (v: number, value: UpdateFrequency) { + setUpdate (v: number, value: UpdateFrequency): void { this._updateFrequencies[v] = value; } getLayout (v: number): PipelineLayoutData { @@ -1260,7 +1260,7 @@ export class LayoutGraphData implements BidirectionalGraph constantMacros = ''; } -export function saveDescriptorDB (ar: OutputArchive, v: DescriptorDB) { +export function saveDescriptorDB (ar: OutputArchive, v: DescriptorDB): void { ar.writeNumber(v.blocks.size); // Map for (const [k1, v1] of v.blocks) { saveDescriptorBlockIndex(ar, JSON.parse(k1)); @@ -1268,7 +1268,7 @@ export function saveDescriptorDB (ar: OutputArchive, v: DescriptorDB) { } } -export function loadDescriptorDB (ar: InputArchive, v: DescriptorDB) { +export function loadDescriptorDB (ar: InputArchive, v: DescriptorDB): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1280,14 +1280,14 @@ export function loadDescriptorDB (ar: InputArchive, v: DescriptorDB) { } } -export function saveRenderPhase (ar: OutputArchive, v: RenderPhase) { +export function saveRenderPhase (ar: OutputArchive, v: RenderPhase): void { ar.writeNumber(v.shaders.size); // Set for (const v1 of v.shaders) { ar.writeString(v1); } } -export function loadRenderPhase (ar: InputArchive, v: RenderPhase) { +export function loadRenderPhase (ar: InputArchive, v: RenderPhase): void { let sz = 0; sz = ar.readNumber(); // Set for (let i1 = 0; i1 !== sz; ++i1) { @@ -1296,7 +1296,7 @@ export function loadRenderPhase (ar: InputArchive, v: RenderPhase) { } } -export function saveLayoutGraph (ar: OutputArchive, g: LayoutGraph) { +export function saveLayoutGraph (ar: OutputArchive, g: LayoutGraph): void { const numVertices = g.numVertices(); const numEdges = g.numEdges(); ar.writeNumber(numVertices); @@ -1335,7 +1335,7 @@ export function saveLayoutGraph (ar: OutputArchive, g: LayoutGraph) { } } -export function loadLayoutGraph (ar: InputArchive, g: LayoutGraph) { +export function loadLayoutGraph (ar: InputArchive, g: LayoutGraph): void { const numVertices = ar.readNumber(); const numEdges = ar.readNumber(); const numStages = ar.readNumber(); @@ -1364,21 +1364,21 @@ export function loadLayoutGraph (ar: InputArchive, g: LayoutGraph) { } } -export function saveUniformData (ar: OutputArchive, v: UniformData) { +export function saveUniformData (ar: OutputArchive, v: UniformData): void { ar.writeNumber(v.uniformID); ar.writeNumber(v.uniformType); ar.writeNumber(v.offset); ar.writeNumber(v.size); } -export function loadUniformData (ar: InputArchive, v: UniformData) { +export function loadUniformData (ar: InputArchive, v: UniformData): void { v.uniformID = ar.readNumber(); v.uniformType = ar.readNumber(); v.offset = ar.readNumber(); v.size = ar.readNumber(); } -export function saveUniformBlockData (ar: OutputArchive, v: UniformBlockData) { +export function saveUniformBlockData (ar: OutputArchive, v: UniformBlockData): void { ar.writeNumber(v.bufferSize); ar.writeNumber(v.uniforms.length); // UniformData[] for (const v1 of v.uniforms) { @@ -1386,7 +1386,7 @@ export function saveUniformBlockData (ar: OutputArchive, v: UniformBlockData) { } } -export function loadUniformBlockData (ar: InputArchive, v: UniformBlockData) { +export function loadUniformBlockData (ar: InputArchive, v: UniformBlockData): void { v.bufferSize = ar.readNumber(); let sz = 0; sz = ar.readNumber(); // UniformData[] @@ -1398,19 +1398,19 @@ export function loadUniformBlockData (ar: InputArchive, v: UniformBlockData) { } } -export function saveDescriptorData (ar: OutputArchive, v: DescriptorData) { +export function saveDescriptorData (ar: OutputArchive, v: DescriptorData): void { ar.writeNumber(v.descriptorID); ar.writeNumber(v.type); ar.writeNumber(v.count); } -export function loadDescriptorData (ar: InputArchive, v: DescriptorData) { +export function loadDescriptorData (ar: InputArchive, v: DescriptorData): void { v.descriptorID = ar.readNumber(); v.type = ar.readNumber(); v.count = ar.readNumber(); } -export function saveDescriptorBlockData (ar: OutputArchive, v: DescriptorBlockData) { +export function saveDescriptorBlockData (ar: OutputArchive, v: DescriptorBlockData): void { ar.writeNumber(v.type); ar.writeNumber(v.visibility); ar.writeNumber(v.offset); @@ -1421,7 +1421,7 @@ export function saveDescriptorBlockData (ar: OutputArchive, v: DescriptorBlockDa } } -export function loadDescriptorBlockData (ar: InputArchive, v: DescriptorBlockData) { +export function loadDescriptorBlockData (ar: InputArchive, v: DescriptorBlockData): void { v.type = ar.readNumber(); v.visibility = ar.readNumber(); v.offset = ar.readNumber(); @@ -1436,7 +1436,7 @@ export function loadDescriptorBlockData (ar: InputArchive, v: DescriptorBlockDat } } -export function saveDescriptorSetLayoutData (ar: OutputArchive, v: DescriptorSetLayoutData) { +export function saveDescriptorSetLayoutData (ar: OutputArchive, v: DescriptorSetLayoutData): void { ar.writeNumber(v.slot); ar.writeNumber(v.capacity); ar.writeNumber(v.uniformBlockCapacity); @@ -1457,7 +1457,7 @@ export function saveDescriptorSetLayoutData (ar: OutputArchive, v: DescriptorSet } } -export function loadDescriptorSetLayoutData (ar: InputArchive, v: DescriptorSetLayoutData) { +export function loadDescriptorSetLayoutData (ar: InputArchive, v: DescriptorSetLayoutData): void { v.slot = ar.readNumber(); v.capacity = ar.readNumber(); v.uniformBlockCapacity = ar.readNumber(); @@ -1485,21 +1485,21 @@ export function loadDescriptorSetLayoutData (ar: InputArchive, v: DescriptorSetL } } -export function saveDescriptorSetData (ar: OutputArchive, v: DescriptorSetData) { +export function saveDescriptorSetData (ar: OutputArchive, v: DescriptorSetData): void { saveDescriptorSetLayoutData(ar, v.descriptorSetLayoutData); saveDescriptorSetLayoutInfo(ar, v.descriptorSetLayoutInfo); // skip, v.descriptorSetLayout: DescriptorSetLayout // skip, v.descriptorSet: DescriptorSet } -export function loadDescriptorSetData (ar: InputArchive, v: DescriptorSetData) { +export function loadDescriptorSetData (ar: InputArchive, v: DescriptorSetData): void { loadDescriptorSetLayoutData(ar, v.descriptorSetLayoutData); loadDescriptorSetLayoutInfo(ar, v.descriptorSetLayoutInfo); // skip, v.descriptorSetLayout: DescriptorSetLayout // skip, v.descriptorSet: DescriptorSet } -export function savePipelineLayoutData (ar: OutputArchive, v: PipelineLayoutData) { +export function savePipelineLayoutData (ar: OutputArchive, v: PipelineLayoutData): void { ar.writeNumber(v.descriptorSets.size); // Map for (const [k1, v1] of v.descriptorSets) { ar.writeNumber(k1); @@ -1507,7 +1507,7 @@ export function savePipelineLayoutData (ar: OutputArchive, v: PipelineLayoutData } } -export function loadPipelineLayoutData (ar: InputArchive, v: PipelineLayoutData) { +export function loadPipelineLayoutData (ar: InputArchive, v: PipelineLayoutData): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1518,7 +1518,7 @@ export function loadPipelineLayoutData (ar: InputArchive, v: PipelineLayoutData) } } -export function saveShaderBindingData (ar: OutputArchive, v: ShaderBindingData) { +export function saveShaderBindingData (ar: OutputArchive, v: ShaderBindingData): void { ar.writeNumber(v.descriptorBindings.size); // Map for (const [k1, v1] of v.descriptorBindings) { ar.writeNumber(k1); @@ -1526,7 +1526,7 @@ export function saveShaderBindingData (ar: OutputArchive, v: ShaderBindingData) } } -export function loadShaderBindingData (ar: InputArchive, v: ShaderBindingData) { +export function loadShaderBindingData (ar: InputArchive, v: ShaderBindingData): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1536,7 +1536,7 @@ export function loadShaderBindingData (ar: InputArchive, v: ShaderBindingData) { } } -export function saveShaderLayoutData (ar: OutputArchive, v: ShaderLayoutData) { +export function saveShaderLayoutData (ar: OutputArchive, v: ShaderLayoutData): void { ar.writeNumber(v.layoutData.size); // Map for (const [k1, v1] of v.layoutData) { ar.writeNumber(k1); @@ -1549,7 +1549,7 @@ export function saveShaderLayoutData (ar: OutputArchive, v: ShaderLayoutData) { } } -export function loadShaderLayoutData (ar: InputArchive, v: ShaderLayoutData) { +export function loadShaderLayoutData (ar: InputArchive, v: ShaderLayoutData): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1567,14 +1567,14 @@ export function loadShaderLayoutData (ar: InputArchive, v: ShaderLayoutData) { } } -export function saveTechniqueData (ar: OutputArchive, v: TechniqueData) { +export function saveTechniqueData (ar: OutputArchive, v: TechniqueData): void { ar.writeNumber(v.passes.length); // ShaderLayoutData[] for (const v1 of v.passes) { saveShaderLayoutData(ar, v1); } } -export function loadTechniqueData (ar: InputArchive, v: TechniqueData) { +export function loadTechniqueData (ar: InputArchive, v: TechniqueData): void { let sz = 0; sz = ar.readNumber(); // ShaderLayoutData[] v.passes.length = sz; @@ -1585,7 +1585,7 @@ export function loadTechniqueData (ar: InputArchive, v: TechniqueData) { } } -export function saveEffectData (ar: OutputArchive, v: EffectData) { +export function saveEffectData (ar: OutputArchive, v: EffectData): void { ar.writeNumber(v.techniques.size); // Map for (const [k1, v1] of v.techniques) { ar.writeString(k1); @@ -1593,7 +1593,7 @@ export function saveEffectData (ar: OutputArchive, v: EffectData) { } } -export function loadEffectData (ar: InputArchive, v: EffectData) { +export function loadEffectData (ar: InputArchive, v: EffectData): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1604,17 +1604,17 @@ export function loadEffectData (ar: InputArchive, v: EffectData) { } } -export function saveShaderProgramData (ar: OutputArchive, v: ShaderProgramData) { +export function saveShaderProgramData (ar: OutputArchive, v: ShaderProgramData): void { savePipelineLayoutData(ar, v.layout); // skip, v.pipelineLayout: PipelineLayout } -export function loadShaderProgramData (ar: InputArchive, v: ShaderProgramData) { +export function loadShaderProgramData (ar: InputArchive, v: ShaderProgramData): void { loadPipelineLayoutData(ar, v.layout); // skip, v.pipelineLayout: PipelineLayout } -export function saveRenderStageData (ar: OutputArchive, v: RenderStageData) { +export function saveRenderStageData (ar: OutputArchive, v: RenderStageData): void { ar.writeNumber(v.descriptorVisibility.size); // Map for (const [k1, v1] of v.descriptorVisibility) { ar.writeNumber(k1); @@ -1622,7 +1622,7 @@ export function saveRenderStageData (ar: OutputArchive, v: RenderStageData) { } } -export function loadRenderStageData (ar: InputArchive, v: RenderStageData) { +export function loadRenderStageData (ar: InputArchive, v: RenderStageData): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -1632,7 +1632,7 @@ export function loadRenderStageData (ar: InputArchive, v: RenderStageData) { } } -export function saveRenderPhaseData (ar: OutputArchive, v: RenderPhaseData) { +export function saveRenderPhaseData (ar: OutputArchive, v: RenderPhaseData): void { ar.writeString(v.rootSignature); ar.writeNumber(v.shaderPrograms.length); // ShaderProgramData[] for (const v1 of v.shaderPrograms) { @@ -1646,7 +1646,7 @@ export function saveRenderPhaseData (ar: OutputArchive, v: RenderPhaseData) { // skip, v.pipelineLayout: PipelineLayout } -export function loadRenderPhaseData (ar: InputArchive, v: RenderPhaseData) { +export function loadRenderPhaseData (ar: InputArchive, v: RenderPhaseData): void { v.rootSignature = ar.readString(); let sz = 0; sz = ar.readNumber(); // ShaderProgramData[] @@ -1665,7 +1665,7 @@ export function loadRenderPhaseData (ar: InputArchive, v: RenderPhaseData) { // skip, v.pipelineLayout: PipelineLayout } -export function saveLayoutGraphData (ar: OutputArchive, g: LayoutGraphData) { +export function saveLayoutGraphData (ar: OutputArchive, g: LayoutGraphData): void { const numVertices = g.numVertices(); const numEdges = g.numEdges(); ar.writeNumber(numVertices); @@ -1729,7 +1729,7 @@ export function saveLayoutGraphData (ar: OutputArchive, g: LayoutGraphData) { } } -export function loadLayoutGraphData (ar: InputArchive, g: LayoutGraphData) { +export function loadLayoutGraphData (ar: InputArchive, g: LayoutGraphData): void { const numVertices = ar.readNumber(); const numEdges = ar.readNumber(); const numStages = ar.readNumber(); diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index 3051497dc36..afbb675ef8d 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -456,7 +456,7 @@ export class SubpassGraph implements BidirectionalGraph getName (v: number): string { return this._names[v]; } - setName (v: number, value: string) { + setName (v: number, value: string): void { this._names[v] = value; } getSubpass (v: number): Subpass { @@ -862,7 +862,7 @@ export class ResourceGraph implements BidirectionalGraph { // UuidGraph const key = this._names[u]; this._valueIndex.delete(key); - this._valueIndex.forEach((v) => { + this._valueIndex.forEach((v): void => { if (v > u) { --v; } }); } @@ -996,7 +996,7 @@ export class ResourceGraph implements BidirectionalGraph getName (v: number): string { return this._names[v]; } - setName (v: number, value: string) { + setName (v: number, value: string): void { this._names[v] = value; } getDesc (v: number): ResourceDesc { @@ -1871,13 +1871,13 @@ export class RenderGraph implements BidirectionalGraph getName (v: number): string { return this._names[v]; } - setName (v: number, value: string) { + setName (v: number, value: string): void { this._names[v] = value; } getLayout (v: number): string { return this._layoutNodes[v]; } - setLayout (v: number, value: string) { + setLayout (v: number, value: string): void { this._layoutNodes[v] = value; } getData (v: number): RenderData { @@ -1886,7 +1886,7 @@ export class RenderGraph implements BidirectionalGraph getValid (v: number): boolean { return this._valid[v]; } - setValid (v: number, value: boolean) { + setValid (v: number, value: boolean): void { this._valid[v] = value; } //----------------------------------------------------------------- diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index 096b847abe7..962f8e9690c 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -496,27 +496,27 @@ export class PipelineStatistics { numInstancingUniformBlocks = 0; } -export function saveLightInfo (ar: OutputArchive, v: LightInfo) { +export function saveLightInfo (ar: OutputArchive, v: LightInfo): void { // skip, v.light: Light ar.writeNumber(v.level); } -export function loadLightInfo (ar: InputArchive, v: LightInfo) { +export function loadLightInfo (ar: InputArchive, v: LightInfo): void { // skip, v.light: Light v.level = ar.readNumber(); } -export function saveDescriptor (ar: OutputArchive, v: Descriptor) { +export function saveDescriptor (ar: OutputArchive, v: Descriptor): void { ar.writeNumber(v.type); ar.writeNumber(v.count); } -export function loadDescriptor (ar: InputArchive, v: Descriptor) { +export function loadDescriptor (ar: InputArchive, v: Descriptor): void { v.type = ar.readNumber(); v.count = ar.readNumber(); } -export function saveDescriptorBlock (ar: OutputArchive, v: DescriptorBlock) { +export function saveDescriptorBlock (ar: OutputArchive, v: DescriptorBlock): void { ar.writeNumber(v.descriptors.size); // Map for (const [k1, v1] of v.descriptors) { ar.writeString(k1); @@ -531,7 +531,7 @@ export function saveDescriptorBlock (ar: OutputArchive, v: DescriptorBlock) { ar.writeNumber(v.count); } -export function loadDescriptorBlock (ar: InputArchive, v: DescriptorBlock) { +export function loadDescriptorBlock (ar: InputArchive, v: DescriptorBlock): void { let sz = 0; sz = ar.readNumber(); // Map for (let i1 = 0; i1 !== sz; ++i1) { @@ -551,7 +551,7 @@ export function loadDescriptorBlock (ar: InputArchive, v: DescriptorBlock) { v.count = ar.readNumber(); } -export function saveDescriptorBlockFlattened (ar: OutputArchive, v: DescriptorBlockFlattened) { +export function saveDescriptorBlockFlattened (ar: OutputArchive, v: DescriptorBlockFlattened): void { ar.writeNumber(v.descriptorNames.length); // string[] for (const v1 of v.descriptorNames) { ar.writeString(v1); @@ -572,7 +572,7 @@ export function saveDescriptorBlockFlattened (ar: OutputArchive, v: DescriptorBl ar.writeNumber(v.count); } -export function loadDescriptorBlockFlattened (ar: InputArchive, v: DescriptorBlockFlattened) { +export function loadDescriptorBlockFlattened (ar: InputArchive, v: DescriptorBlockFlattened): void { let sz = 0; sz = ar.readNumber(); // string[] v.descriptorNames.length = sz; @@ -602,21 +602,21 @@ export function loadDescriptorBlockFlattened (ar: InputArchive, v: DescriptorBlo v.count = ar.readNumber(); } -export function saveDescriptorBlockIndex (ar: OutputArchive, v: DescriptorBlockIndex) { +export function saveDescriptorBlockIndex (ar: OutputArchive, v: DescriptorBlockIndex): void { ar.writeNumber(v.updateFrequency); ar.writeNumber(v.parameterType); ar.writeNumber(v.descriptorType); ar.writeNumber(v.visibility); } -export function loadDescriptorBlockIndex (ar: InputArchive, v: DescriptorBlockIndex) { +export function loadDescriptorBlockIndex (ar: InputArchive, v: DescriptorBlockIndex): void { v.updateFrequency = ar.readNumber(); v.parameterType = ar.readNumber(); v.descriptorType = ar.readNumber(); v.visibility = ar.readNumber(); } -export function saveResolvePair (ar: OutputArchive, v: ResolvePair) { +export function saveResolvePair (ar: OutputArchive, v: ResolvePair): void { ar.writeString(v.source); ar.writeString(v.target); ar.writeNumber(v.resolveFlags); @@ -624,7 +624,7 @@ export function saveResolvePair (ar: OutputArchive, v: ResolvePair) { ar.writeNumber(v.mode1); } -export function loadResolvePair (ar: InputArchive, v: ResolvePair) { +export function loadResolvePair (ar: InputArchive, v: ResolvePair): void { v.source = ar.readString(); v.target = ar.readString(); v.resolveFlags = ar.readNumber(); @@ -632,7 +632,7 @@ export function loadResolvePair (ar: InputArchive, v: ResolvePair) { v.mode1 = ar.readNumber(); } -export function saveCopyPair (ar: OutputArchive, v: CopyPair) { +export function saveCopyPair (ar: OutputArchive, v: CopyPair): void { ar.writeString(v.source); ar.writeString(v.target); ar.writeNumber(v.mipLevels); @@ -645,7 +645,7 @@ export function saveCopyPair (ar: OutputArchive, v: CopyPair) { ar.writeNumber(v.targetPlaneSlice); } -export function loadCopyPair (ar: InputArchive, v: CopyPair) { +export function loadCopyPair (ar: InputArchive, v: CopyPair): void { v.source = ar.readString(); v.target = ar.readString(); v.mipLevels = ar.readNumber(); @@ -658,7 +658,7 @@ export function loadCopyPair (ar: InputArchive, v: CopyPair) { v.targetPlaneSlice = ar.readNumber(); } -export function saveMovePair (ar: OutputArchive, v: MovePair) { +export function saveMovePair (ar: OutputArchive, v: MovePair): void { ar.writeString(v.source); ar.writeString(v.target); ar.writeNumber(v.mipLevels); @@ -668,7 +668,7 @@ export function saveMovePair (ar: OutputArchive, v: MovePair) { ar.writeNumber(v.targetPlaneSlice); } -export function loadMovePair (ar: InputArchive, v: MovePair) { +export function loadMovePair (ar: InputArchive, v: MovePair): void { v.source = ar.readString(); v.target = ar.readString(); v.mipLevels = ar.readNumber(); @@ -678,7 +678,7 @@ export function loadMovePair (ar: InputArchive, v: MovePair) { v.targetPlaneSlice = ar.readNumber(); } -export function savePipelineStatistics (ar: OutputArchive, v: PipelineStatistics) { +export function savePipelineStatistics (ar: OutputArchive, v: PipelineStatistics): void { ar.writeNumber(v.numRenderPasses); ar.writeNumber(v.numManagedTextures); ar.writeNumber(v.totalManagedTextures); @@ -692,7 +692,7 @@ export function savePipelineStatistics (ar: OutputArchive, v: PipelineStatistics ar.writeNumber(v.numInstancingUniformBlocks); } -export function loadPipelineStatistics (ar: InputArchive, v: PipelineStatistics) { +export function loadPipelineStatistics (ar: InputArchive, v: PipelineStatistics): void { v.numRenderPasses = ar.readNumber(); v.numManagedTextures = ar.readNumber(); v.totalManagedTextures = ar.readNumber(); From eccbbe1c8cb96dc1d94ce194cecb877c49f00da3 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 15:28:43 +0800 Subject: [PATCH 21/57] adding comment --- cocos/rendering/custom/pipeline.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 582546ff523..c982b1357f4 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -40,6 +40,12 @@ import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, Reso import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; +/** + * @en PipelineRuntime is the runtime of both classical and custom pipelines. + * It is used internally and should not be called directly. + * @zh PipelineRuntime是经典管线以及自定义管线的运行时。 + * 属于内部实现,用户不应直接调用。 + */ export interface PipelineRuntime { activate (swapchain: Swapchain): boolean; destroy (): boolean; From 98e4af50ade67b63fbffae7edf4b46b309e407c1 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 17:52:27 +0800 Subject: [PATCH 22/57] add PipelineRuntime document --- cocos/rendering/custom/pipeline.ts | 96 +++++++++++++++++ .../pipeline/custom/RenderInterfaceTypes.h | 102 ++++++++++++++++++ 2 files changed, 198 insertions(+) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index c982b1357f4..859f9cc1a43 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -41,32 +41,128 @@ import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; /** + * @internal * @en PipelineRuntime is the runtime of both classical and custom pipelines. * It is used internally and should not be called directly. * @zh PipelineRuntime是经典管线以及自定义管线的运行时。 * 属于内部实现,用户不应直接调用。 */ export interface PipelineRuntime { + /** + * @en Activate PipelineRuntime with default swapchain + * @zh 用默认交换链初始化PipelineRuntime + */ activate (swapchain: Swapchain): boolean; + /** + * @en Destroy resources of PipelineRuntime + * @zh 销毁PipelineRuntime所持资源 + */ destroy (): boolean; + /** + * @en Render contents of cameras + * @zh 渲染各相机需要绘制的内容 + */ render (cameras: Camera[]): void; + /** + * @en Get graphics device + * @zh 获得图形设备 + */ readonly device: Device; + /** + * @en Get user macros + * @zh 获得用户宏列表 + */ readonly macros: MacroRecord; + /** + * @en Get global descriptor set manager + * @zh 获得全局(Global)级别描述符集(DescriptorSet)管理器 + */ readonly globalDSManager: GlobalDSManager; + /** + * @en Get global descriptor set layout + * @zh 获得全局(Global)级别描述符集的布局(DescriptorSet Layout) + */ readonly descriptorSetLayout: DescriptorSetLayout; + /** + * @en Get global descriptor set + * @zh 获得全局(Global)级别描述符集(DescriptorSet) + */ readonly descriptorSet: DescriptorSet; + /** + * @en Get command buffers of render pipeline + * @zh 获得渲染管线的命令缓冲(CommandBuffer)列表 + */ readonly commandBuffers: CommandBuffer[]; + /** + * @en Get scene data of render pipeline. + * Scene data contains render configurations of the current scene. + * @zh 获得渲染管线相关的场景数据,此场景数据一般包含渲染所需配置信息 + */ readonly pipelineSceneData: PipelineSceneData; + /** + * @en Get constant macros. + * Constant macro is platform-dependent and immutable. + * @zh 获得常量宏列表,常量宏平台相关且无法修改 + */ readonly constantMacros: string; + /** + * @en Get profiler model. + * This model is used to render profile information in Debug mode. + * @zh 获得分析工具(Profiler)的渲染实例,用于Debug模式下显示调试与性能检测信息 + */ profiler: Model | null; + /** + * @en Get geometry renderer. + * Geometry renderer is used to render procedural geometries. + * @zh 获得几何渲染器(GeometryRenderer),几何渲染器用于程序化渲染基础几何图形 + */ readonly geometryRenderer: GeometryRenderer | null; + /** + * @en Get shading scale. + * Shading scale affects shading texels per pixel. + * @zh 获得渲染倍率(ShadingScale),每像素(pixel)绘制的纹素(texel)会根据渲染倍率进行调整。 + */ shadingScale: number; + /** + * @en Get macro as string. + * @zh 根据宏名获得字符串 + * @param name @en Name of macro @zh 宏的名字 + */ getMacroString (name: string): string; + /** + * @en Get macro as integer. + * @zh 根据宏名获得整型 + * @param name @en Name of macro @zh 宏的名字 + */ getMacroInt (name: string): number; + /** + * @en Get macro as boolean. + * @zh 根据宏名获得布尔值 + * @param name @en Name of macro @zh 宏的名字 + */ getMacroBool (name: string): boolean; + /** + * @en Assign string value to macro. + * @zh 给宏赋值字符串 + * @param name @en Name of macro @zh 宏的名字 + */ setMacroString (name: string, value: string): void; + /** + * @en Assign integer value to macro. + * @zh 给宏赋值整型 + * @param name @en Name of macro @zh 宏的名字 + */ setMacroInt (name: string, value: number): void; + /** + * @en Assign boolean value to macro. + * @zh 给宏赋值布尔值 + * @param name @en Name of macro @zh 宏的名字 + */ setMacroBool (name: string, value: boolean): void; + /** + * @en trigger pipeline state change event + * @zh 触发管线状态更新事件 + */ onGlobalPipelineStateChanged (): void; } diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index be9cfdd205f..de215ec87cb 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -77,6 +77,13 @@ namespace cc { namespace render { +/** + * @internal + * @en PipelineRuntime is the runtime of both classical and custom pipelines. + * It is used internally and should not be called directly. + * @zh PipelineRuntime是经典管线以及自定义管线的运行时。 + * 属于内部实现,用户不应直接调用。 + */ class PipelineRuntime { public: PipelineRuntime() noexcept = default; @@ -86,28 +93,123 @@ class PipelineRuntime { PipelineRuntime& operator=(PipelineRuntime const& rhs) = delete; virtual ~PipelineRuntime() noexcept = default; + /** + * @en Activate PipelineRuntime with default swapchain + * @zh 用默认交换链初始化PipelineRuntime + */ virtual bool activate(gfx::Swapchain *swapchain) = 0; + /** + * @en Destroy resources of PipelineRuntime + * @zh 销毁PipelineRuntime所持资源 + */ virtual bool destroy() noexcept = 0; + /** + * @en Render contents of cameras + * @zh 渲染各相机需要绘制的内容 + */ virtual void render(const ccstd::vector &cameras) = 0; + /** + * @en Get graphics device + * @zh 获得图形设备 + */ virtual gfx::Device *getDevice() const = 0; + /** + * @en Get user macros + * @zh 获得用户宏列表 + */ virtual const MacroRecord &getMacros() const = 0; + /** + * @en Get global descriptor set manager + * @zh 获得全局(Global)级别描述符集(DescriptorSet)管理器 + */ virtual pipeline::GlobalDSManager *getGlobalDSManager() const = 0; + /** + * @en Get global descriptor set layout + * @zh 获得全局(Global)级别描述符集的布局(DescriptorSet Layout) + */ virtual gfx::DescriptorSetLayout *getDescriptorSetLayout() const = 0; + /** + * @en Get global descriptor set + * @zh 获得全局(Global)级别描述符集(DescriptorSet) + */ virtual gfx::DescriptorSet *getDescriptorSet() const = 0; + /** + * @en Get command buffers of render pipeline + * @zh 获得渲染管线的命令缓冲(CommandBuffer)列表 + */ virtual const ccstd::vector &getCommandBuffers() const = 0; + /** + * @en Get scene data of render pipeline. + * Scene data contains render configurations of the current scene. + * @zh 获得渲染管线相关的场景数据,此场景数据一般包含渲染所需配置信息 + */ virtual pipeline::PipelineSceneData *getPipelineSceneData() const = 0; + /** + * @en Get constant macros. + * Constant macro is platform-dependent and immutable. + * @zh 获得常量宏列表,常量宏平台相关且无法修改 + */ virtual const ccstd::string &getConstantMacros() const = 0; + /** + * @en Get profiler model. + * This model is used to render profile information in Debug mode. + * @zh 获得分析工具(Profiler)的渲染实例,用于Debug模式下显示调试与性能检测信息 + */ virtual scene::Model *getProfiler() const = 0; virtual void setProfiler(scene::Model *profiler) = 0; + /** + * @en Get geometry renderer. + * Geometry renderer is used to render procedural geometries. + * @zh 获得几何渲染器(GeometryRenderer),几何渲染器用于程序化渲染基础几何图形 + */ virtual pipeline::GeometryRenderer *getGeometryRenderer() const = 0; + /** + * @en Get shading scale. + * Shading scale affects shading texels per pixel. + * @zh 获得渲染倍率(ShadingScale),每像素(pixel)绘制的纹素(texel)会根据渲染倍率进行调整。 + */ virtual float getShadingScale() const = 0; virtual void setShadingScale(float scale) = 0; + /** + * @en Get macro as string. + * @zh 根据宏名获得字符串 + * @param name @en Name of macro @zh 宏的名字 + */ virtual const ccstd::string &getMacroString(const ccstd::string &name) const = 0; + /** + * @en Get macro as integer. + * @zh 根据宏名获得整型 + * @param name @en Name of macro @zh 宏的名字 + */ virtual int32_t getMacroInt(const ccstd::string &name) const = 0; + /** + * @en Get macro as boolean. + * @zh 根据宏名获得布尔值 + * @param name @en Name of macro @zh 宏的名字 + */ virtual bool getMacroBool(const ccstd::string &name) const = 0; + /** + * @en Assign string value to macro. + * @zh 给宏赋值字符串 + * @param name @en Name of macro @zh 宏的名字 + */ virtual void setMacroString(const ccstd::string &name, const ccstd::string &value) = 0; + /** + * @en Assign integer value to macro. + * @zh 给宏赋值整型 + * @param name @en Name of macro @zh 宏的名字 + */ virtual void setMacroInt(const ccstd::string &name, int32_t value) = 0; + /** + * @en Assign boolean value to macro. + * @zh 给宏赋值布尔值 + * @param name @en Name of macro @zh 宏的名字 + */ virtual void setMacroBool(const ccstd::string &name, bool value) = 0; + /** + * @en trigger pipeline state change event + * @zh 触发管线状态更新事件 + */ virtual void onGlobalPipelineStateChanged() = 0; virtual void setValue(const ccstd::string &name, int32_t value) = 0; virtual void setValue(const ccstd::string &name, bool value) = 0; From 890e00683ba1b9ed242973726e2b4d8948b60e82 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 17:55:36 +0800 Subject: [PATCH 23/57] update comment --- cocos/rendering/custom/pipeline.ts | 2 +- native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 859f9cc1a43..73a4d635dee 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -60,7 +60,7 @@ export interface PipelineRuntime { destroy (): boolean; /** * @en Render contents of cameras - * @zh 渲染各相机需要绘制的内容 + * @zh 根据相机进行绘制 */ render (cameras: Camera[]): void; /** diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index de215ec87cb..a49497870b6 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -105,7 +105,7 @@ class PipelineRuntime { virtual bool destroy() noexcept = 0; /** * @en Render contents of cameras - * @zh 渲染各相机需要绘制的内容 + * @zh 根据相机进行绘制 */ virtual void render(const ccstd::vector &cameras) = 0; /** From 24149c81b12cc5610fbe9dfb85d34ad54b8df2b4 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 18:09:06 +0800 Subject: [PATCH 24/57] adding enum comments --- cocos/rendering/custom/pipeline.ts | 7 ++++++- .../cocos/renderer/pipeline/custom/RenderInterfaceTypes.h | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 73a4d635dee..5a053c2bc3f 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -160,12 +160,17 @@ export interface PipelineRuntime { */ setMacroBool (name: string, value: boolean): void; /** - * @en trigger pipeline state change event + * @en Trigger pipeline state change event * @zh 触发管线状态更新事件 */ onGlobalPipelineStateChanged (): void; } +/** + * @en Type of render pipeline. + * Different types of pipeline have different hardward capabilities and interfaces. + * @zh 管线类型,不同类型的管线具有不同的硬件能力与接口 + */ export enum PipelineType { BASIC, STANDARD, diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index a49497870b6..9f51d93c1b7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -207,7 +207,7 @@ class PipelineRuntime { */ virtual void setMacroBool(const ccstd::string &name, bool value) = 0; /** - * @en trigger pipeline state change event + * @en Trigger pipeline state change event * @zh 触发管线状态更新事件 */ virtual void onGlobalPipelineStateChanged() = 0; @@ -218,6 +218,11 @@ class PipelineRuntime { virtual bool isRenderQueueReset() const = 0; }; +/** + * @en Type of render pipeline. + * Different types of pipeline have different hardward capabilities and interfaces. + * @zh 管线类型,不同类型的管线具有不同的硬件能力与接口 + */ enum class PipelineType { BASIC, STANDARD, From e53d130c9d2229bb035297f56f250559a4e58a15 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 18:22:34 +0800 Subject: [PATCH 25/57] change beta and experimental --- cocos/rendering/custom/pipeline.ts | 29 ++++++++++++------- .../pipeline/custom/RenderInterfaceTypes.h | 29 ++++++++++++------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 5a053c2bc3f..70266a34f9c 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -201,7 +201,7 @@ export class PipelineCapabilities { export interface RenderNode { name: string; /** - * @beta function signature might change + * @experimental */ setCustomBehavior (name: string): void; } @@ -223,7 +223,7 @@ export interface Setter extends RenderNode { export interface RenderQueueBuilder extends Setter { /** - * @deprecated method will be removed in 3.9.0 + * @deprecated Method will be removed in 3.9.0 */ addSceneOfCamera ( camera: Camera, @@ -241,7 +241,7 @@ export interface RenderQueueBuilder extends Setter { clearRenderTarget (name: string, color?: Color): void; setViewport (viewport: Viewport): void; /** - * @beta function signature might change + * @experimental */ addCustomCommand (customBehavior: string): void; } @@ -358,7 +358,7 @@ export interface RenderSubpassBuilder extends Setter { addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; showStatistics: boolean; /** - * @beta function signature might change + * @experimental */ setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } @@ -398,7 +398,7 @@ export interface ComputeSubpassBuilder extends Setter { slotName: string): void; addQueue (phaseName?: string): ComputeQueueBuilder; /** - * @beta function signature might change + * @experimental */ setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } @@ -413,17 +413,26 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { accessType: AccessType, slotName: string): void; /** - * @beta function signature might change + * @beta Feature is under development */ addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; + /** + * @beta Feature is under development + */ addRenderSubpass (subpassName: string): RenderSubpassBuilder; + /** + * @beta Feature is under development + */ addMultisampleRenderSubpass ( count: number, quality: number, subpassName: string): MultisampleRenderSubpassBuilder; + /** + * @experimental + */ addComputeSubpass (subpassName?: string): ComputeSubpassBuilder; /** - * @beta function signature might change + * @experimental */ setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } @@ -445,7 +454,7 @@ export interface ComputePassBuilder extends Setter { addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; addQueue (phaseName?: string): ComputeQueueBuilder; /** - * @beta function signature might change + * @experimental */ setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } @@ -511,14 +520,14 @@ export interface Pipeline extends BasicPipeline { addUploadPass (uploadPairs: UploadPair[]): void; addMovePass (movePairs: MovePair[]): void; /** - * @beta function signature might change + * @experimental */ addCustomBuffer ( name: string, info: BufferInfo, type: string): number; /** - * @beta function signature might change + * @experimental */ addCustomTexture ( name: string, diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 9f51d93c1b7..f11249f3a02 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -275,7 +275,7 @@ class RenderNode { virtual ccstd::string getName() const = 0; virtual void setName(const ccstd::string &name) = 0; /** - * @beta function signature might change + * @experimental */ virtual void setCustomBehavior(const ccstd::string &name) = 0; }; @@ -303,7 +303,7 @@ class RenderQueueBuilder : public Setter { RenderQueueBuilder() noexcept = default; /** - * @deprecated method will be removed in 3.9.0 + * @deprecated Method will be removed in 3.9.0 */ virtual void addSceneOfCamera(scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) = 0; virtual void addFullscreenQuad(Material *material, uint32_t passID, SceneFlags sceneFlags) = 0; @@ -311,7 +311,7 @@ class RenderQueueBuilder : public Setter { virtual void clearRenderTarget(const ccstd::string &name, const gfx::Color &color) = 0; virtual void setViewport(const gfx::Viewport &viewport) = 0; /** - * @beta function signature might change + * @experimental */ virtual void addCustomCommand(std::string_view customBehavior) = 0; void addSceneOfCamera(scene::Camera *camera, LightInfo light) { @@ -435,7 +435,7 @@ class RenderSubpassBuilder : public Setter { virtual bool getShowStatistics() const = 0; virtual void setShowStatistics(bool enable) = 0; /** - * @beta function signature might change + * @experimental */ virtual void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) = 0; void addRenderTarget(const ccstd::string &name, AccessType accessType) { @@ -522,7 +522,7 @@ class ComputeSubpassBuilder : public Setter { virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** - * @beta function signature might change + * @experimental */ virtual void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) = 0; void addTexture(const ccstd::string &name, const ccstd::string &slotName) { @@ -543,14 +543,23 @@ class RenderPassBuilder : public BasicRenderPassBuilder { virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; /** - * @beta function signature might change + * @beta Feature is under development */ virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; + /** + * @beta Feature is under development + */ virtual RenderSubpassBuilder *addRenderSubpass(const ccstd::string &subpassName) = 0; + /** + * @beta Feature is under development + */ virtual MultisampleRenderSubpassBuilder *addMultisampleRenderSubpass(uint32_t count, uint32_t quality, const ccstd::string &subpassName) = 0; + /** + * @experimental + */ virtual ComputeSubpassBuilder *addComputeSubpass(const ccstd::string &subpassName) = 0; /** - * @beta function signature might change + * @experimental */ virtual void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) = 0; void addMaterialTexture(const ccstd::string &resourceName) { @@ -571,7 +580,7 @@ class ComputePassBuilder : public Setter { virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** - * @beta function signature might change + * @experimental */ virtual void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) = 0; void addTexture(const ccstd::string &name, const ccstd::string &slotName) { @@ -649,11 +658,11 @@ class Pipeline : public BasicPipeline { virtual void addUploadPass(ccstd::vector &uploadPairs) = 0; virtual void addMovePass(const ccstd::vector &movePairs) = 0; /** - * @beta function signature might change + * @experimental */ virtual uint32_t addCustomBuffer(const ccstd::string &name, const gfx::BufferInfo &info, const std::string &type) = 0; /** - * @beta function signature might change + * @experimental */ virtual uint32_t addCustomTexture(const ccstd::string &name, const gfx::TextureInfo &info, const std::string &type) = 0; uint32_t addStorageBuffer(const ccstd::string &name, gfx::Format format, uint32_t size) { From e6b2a5bff6d248bbee3323e364e58c2fe56d469a Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 18:59:34 +0800 Subject: [PATCH 26/57] PipelineType added --- cocos/rendering/custom/pipeline.ts | 28 +++++++++++++++++++ .../pipeline/custom/RenderInterfaceTypes.h | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 70266a34f9c..f0790d70539 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -172,7 +172,25 @@ export interface PipelineRuntime { * @zh 管线类型,不同类型的管线具有不同的硬件能力与接口 */ export enum PipelineType { + /** + * @en Basic render pipeline. + * Basic render pipeline is available on all platforms. + * The corresponding interface is {@link BasicPipeline} + * @zh 基础渲染管线,全平台支持。对应接口为 {@link BasicPipeline} + */ BASIC, + /** + * @en Standard render pipeline. + * Standard render pipeline supports compute shader and subpass rendering + * and works well on Tile-based GPUs. + * It is available on all native platforms and supports Vulkan, GLES3 and Metal backends. + * The corresponding interface is {@link Pipeline} + * @zh 标准渲染管线. + * 标准渲染管线支持计算着色器(Compute Shader)与次通道渲染(Subpass rendering)。 + * 能充分利用Tile-based GPU,适合移动平台。 + * 支持所有原生平台,以及Vulkan、GLES3、Metal图形后端。 + * 对应接口为{@link Pipeline} + */ STANDARD, } @@ -216,7 +234,13 @@ export interface Setter extends RenderNode { setArrayBuffer (name: string, arrayBuffer: ArrayBuffer): void; setBuffer (name: string, buffer: Buffer): void; setTexture (name: string, texture: Texture): void; + /** + * @deprecated Method will be removed in 3.9.0 + */ setReadWriteBuffer (name: string, buffer: Buffer): void; + /** + * @deprecated Method will be removed in 3.9.0 + */ setReadWriteTexture (name: string, texture: Texture): void; setSampler (name: string, sampler: Sampler): void; } @@ -270,6 +294,10 @@ export interface BasicRenderPassBuilder extends Setter { showStatistics: boolean; } +/** + * @en BasicPipeline + * @zh 基础渲染管线 + */ export interface BasicPipeline extends PipelineRuntime { readonly type: PipelineType; readonly capabilities: PipelineCapabilities; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index f11249f3a02..22f521d77bd 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -224,7 +224,25 @@ class PipelineRuntime { * @zh 管线类型,不同类型的管线具有不同的硬件能力与接口 */ enum class PipelineType { + /** + * @en Basic render pipeline. + * Basic render pipeline is available on all platforms. + * The corresponding interface is {@link BasicPipeline} + * @zh 基础渲染管线,全平台支持。对应接口为 {@link BasicPipeline} + */ BASIC, + /** + * @en Standard render pipeline. + * Standard render pipeline supports compute shader and subpass rendering + * and works well on Tile-based GPUs. + * It is available on all native platforms and supports Vulkan, GLES3 and Metal backends. + * The corresponding interface is {@link Pipeline} + * @zh 标准渲染管线. + * 标准渲染管线支持计算着色器(Compute Shader)与次通道渲染(Subpass rendering)。 + * 能充分利用Tile-based GPU,适合移动平台。 + * 支持所有原生平台,以及Vulkan、GLES3、Metal图形后端。 + * 对应接口为{@link Pipeline} + */ STANDARD, }; @@ -293,7 +311,13 @@ class Setter : public RenderNode { virtual void setArrayBuffer(const ccstd::string &name, const ArrayBuffer *arrayBuffer) = 0; virtual void setBuffer(const ccstd::string &name, gfx::Buffer *buffer) = 0; virtual void setTexture(const ccstd::string &name, gfx::Texture *texture) = 0; + /** + * @deprecated Method will be removed in 3.9.0 + */ virtual void setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) = 0; + /** + * @deprecated Method will be removed in 3.9.0 + */ virtual void setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) = 0; virtual void setSampler(const ccstd::string &name, gfx::Sampler *sampler) = 0; }; @@ -378,6 +402,10 @@ class BasicRenderPassBuilder : public Setter { } }; +/** + * @en BasicPipeline + * @zh 基础渲染管线 + */ class BasicPipeline : public PipelineRuntime { public: BasicPipeline() noexcept = default; From 420da7769562982e42114f3c8ae473a816793725 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Sun, 25 Jun 2023 19:06:40 +0800 Subject: [PATCH 27/57] update PipelineType --- cocos/rendering/custom/pipeline.ts | 10 +++++----- .../renderer/pipeline/custom/RenderInterfaceTypes.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index f0790d70539..a9efa8479d1 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -181,14 +181,14 @@ export enum PipelineType { BASIC, /** * @en Standard render pipeline. - * Standard render pipeline supports compute shader and subpass rendering - * and works well on Tile-based GPUs. - * It is available on all native platforms and supports Vulkan, GLES3 and Metal backends. + * Standard render pipeline supports compute shader and subpass rendering. + * It works well on Tile-based GPUs and is available on all native platforms. + * Vulkan, GLES3 and Metal backends are supported. * The corresponding interface is {@link Pipeline} * @zh 标准渲染管线. * 标准渲染管线支持计算着色器(Compute Shader)与次通道渲染(Subpass rendering)。 - * 能充分利用Tile-based GPU,适合移动平台。 - * 支持所有原生平台,以及Vulkan、GLES3、Metal图形后端。 + * 能充分利用Tile-based GPU,支持所有原生平台并对移动平台特别优化。 + * 支持Vulkan、GLES3、Metal图形后端。 * 对应接口为{@link Pipeline} */ STANDARD, diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 22f521d77bd..66f669aabc0 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -233,14 +233,14 @@ enum class PipelineType { BASIC, /** * @en Standard render pipeline. - * Standard render pipeline supports compute shader and subpass rendering - * and works well on Tile-based GPUs. - * It is available on all native platforms and supports Vulkan, GLES3 and Metal backends. + * Standard render pipeline supports compute shader and subpass rendering. + * It works well on Tile-based GPUs and is available on all native platforms. + * Vulkan, GLES3 and Metal backends are supported. * The corresponding interface is {@link Pipeline} * @zh 标准渲染管线. * 标准渲染管线支持计算着色器(Compute Shader)与次通道渲染(Subpass rendering)。 - * 能充分利用Tile-based GPU,适合移动平台。 - * 支持所有原生平台,以及Vulkan、GLES3、Metal图形后端。 + * 能充分利用Tile-based GPU,支持所有原生平台并对移动平台特别优化。 + * 支持Vulkan、GLES3、Metal图形后端。 * 对应接口为{@link Pipeline} */ STANDARD, From 74e32f5665efa5c4aa73592a583fe0b9a644d03b Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 27 Jun 2023 13:42:23 +0800 Subject: [PATCH 28/57] add doc --- cocos/rendering/custom/pipeline.ts | 110 ++++++++++++++++++ .../pipeline/custom/RenderInterfaceTypes.h | 110 ++++++++++++++++++ 2 files changed, 220 insertions(+) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index a9efa8479d1..9ae36fe86c8 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -205,10 +205,39 @@ export function getPipelineTypeName (e: PipelineType): string { } } +/** + * @en Render subpass capabilities. + * Tile-based GPUs support reading color or depth_stencil attachment in pixel shader. + * Our implementation is based-on Vulkan abstraction (aka input attachment), + * and it is emulated on other graphics backends. + * For example, in GLES3 we have used various framebuffer fetch (FBF) extensions. + * As a result, different backends and hardwares support different input attachment features. + * User should inspect pipeline capabilities when implementing tile-based rendering algorithms. + * Using unsupported feature is undefined behaviour. + * @zh 次通道渲染能力 + * Tile-based GPU可以在像素着色器读取当前像素的值。 + * 我们的抽象方式基于Vulkan的input attachment,并在其他图形后端模拟了这个功能。 + * 比如在GLES3上,我们使用了多种framebuffer fetch (FBF) 扩展来实现这个功能。 + * 所以对于不同的硬件以及图形API,支持的能力是略有不同的。 + * 在编写渲染算法时,应该查询当前设备的能力,来选择合适的tile-based算法。 + * 使用硬件不支持的特性,会导致未定义行为。 + */ export enum SubpassCapabilities { NONE = 0, + /** + * @en Supports read depth/stencil value at current pixel. + * @zh 支持读取当前像素的depth/stencil值 + */ INPUT_DEPTH_STENCIL = 1 << 0, + /** + * @en Supports read color value 0 at current pixel. + * @zh 支持读取当前像素第0个颜色值 + */ INPUT_COLOR = 1 << 1, + /** + * @en Supports read color values at current pixel. + * @zh 支持读取当前像素任意颜色值 + */ INPUT_COLOR_MRT = 1 << 2, } @@ -216,7 +245,17 @@ export class PipelineCapabilities { subpass: SubpassCapabilities = SubpassCapabilities.NONE; } +/** + * @en base class of render graph node. + * A node of render graph represents a specific type of rendering operation. + * A render graph consists of these nodes and form a forest(which is a set of trees). + * @zh RenderGraph中节点的基类,每个RenderGraph节点代表一种渲染操作,并构成一个森林(一组树) + */ export interface RenderNode { + /** + * @en Get debug name of current node. + * @zh 获得当前节点调试用的名字 + */ name: string; /** * @experimental @@ -224,15 +263,79 @@ export interface RenderNode { setCustomBehavior (name: string): void; } +/** + * @en Render node which supports setting uniforms and descriptors. + * @zh 节点支持设置常量值(uniform/constant)与描述符 + */ export interface Setter extends RenderNode { + /** + * @en Set matrix4x4 常量(uniform) which consists of 16 floats (64 bytes). + * @zh 设置4x4矩阵,常量(uniform)有16个float (64 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setMat4 (name: string, mat: Mat4): void; + /** + * @en Set quaternion uniform which consists of 4 floats (16 bytes). + * @zh 设置四元数向量,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setQuaternion (name: string, quat: Quat): void; + /** + * @en Set color uniform which consists of 4 floats (16 bytes). + * @zh 设置颜色值,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setColor (name: string, color: Color): void; + /** + * @en Set vector4 uniform which consists of 4 floats (16 bytes). + * @zh 设置vector4向量,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setVec4 (name: string, vec: Vec4): void; + /** + * @en Set vector2 uniform which consists of 2 floats (8 bytes). + * @zh 设置vector2向量,常量(uniform)有2个float (8 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setVec2 (name: string, vec: Vec2): void; + /** + * @en Set float uniform (4 bytes). + * @zh 设置浮点值 (4 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ setFloat (name: string, v: number): void; + /** + * @en Set uniform array. + * Size and type of the data should match the corresponding uniforms in the shader. + * Mismatches will cause undefined behaviour. + * Memory alignment is not required. + * @zh 设置数组。类型与大小需要与着色器中的常量(uniform)相匹配,不匹配会引起未定义行为。 + * 内存地址不需要对齐。 + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + * @param arrayBuffer @en array of bytes @zh byte数组 + */ setArrayBuffer (name: string, arrayBuffer: ArrayBuffer): void; + /** + * @en Set buffer descriptor. + * Size and type of the buffer should match the one in shader. + * Buffer should be in read states and satisfy shader stage visibilities. + * Mismatches will cause undefined behaviour. + * @zh 设置缓冲(buffer)描述符。大小与类型需要与着色器中的一致,处于只读状态且着色阶段可见。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + * @param buffer @en readonly buffer @zh 只读的缓冲 + */ setBuffer (name: string, buffer: Buffer): void; + /** + * @en Set texture descriptor. + * Type of the texture should match the one in shader. + * Texture should be in read states and satisfy shader stage visibilities. + * Mismatches will cause undefined behaviour. + * @zh 设置贴图描述符。类型需要与着色器中的一致,处于只读状态且着色阶段可见。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + * @param texture @en readonly texture @zh 只读的贴图 + */ setTexture (name: string, texture: Texture): void; /** * @deprecated Method will be removed in 3.9.0 @@ -242,6 +345,13 @@ export interface Setter extends RenderNode { * @deprecated Method will be removed in 3.9.0 */ setReadWriteTexture (name: string, texture: Texture): void; + /** + * @en Set sampler descriptor. + * Type of the sampler should match the one in shader. + * @zh 设置采样器描述符。类型需要与着色器中的一致。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + */ setSampler (name: string, sampler: Sampler): void; } diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 66f669aabc0..901bc946ca7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -246,10 +246,39 @@ enum class PipelineType { STANDARD, }; +/** + * @en Render subpass capabilities. + * Tile-based GPUs support reading color or depth_stencil attachment in pixel shader. + * Our implementation is based-on Vulkan abstraction (aka input attachment), + * and it is emulated on other graphics backends. + * For example, in GLES3 we have used various framebuffer fetch (FBF) extensions. + * As a result, different backends and hardwares support different input attachment features. + * User should inspect pipeline capabilities when implementing tile-based rendering algorithms. + * Using unsupported feature is undefined behaviour. + * @zh 次通道渲染能力 + * Tile-based GPU可以在像素着色器读取当前像素的值。 + * 我们的抽象方式基于Vulkan的input attachment,并在其他图形后端模拟了这个功能。 + * 比如在GLES3上,我们使用了多种framebuffer fetch (FBF) 扩展来实现这个功能。 + * 所以对于不同的硬件以及图形API,支持的能力是略有不同的。 + * 在编写渲染算法时,应该查询当前设备的能力,来选择合适的tile-based算法。 + * 使用硬件不支持的特性,会导致未定义行为。 + */ enum class SubpassCapabilities : uint32_t { NONE = 0, + /** + * @en Supports read depth/stencil value at current pixel. + * @zh 支持读取当前像素的depth/stencil值 + */ INPUT_DEPTH_STENCIL = 1 << 0, + /** + * @en Supports read color value 0 at current pixel. + * @zh 支持读取当前像素第0个颜色值 + */ INPUT_COLOR = 1 << 1, + /** + * @en Supports read color values at current pixel. + * @zh 支持读取当前像素任意颜色值 + */ INPUT_COLOR_MRT = 1 << 2, }; @@ -281,6 +310,12 @@ struct PipelineCapabilities { SubpassCapabilities subpass{SubpassCapabilities::NONE}; }; +/** + * @en base class of render graph node. + * A node of render graph represents a specific type of rendering operation. + * A render graph consists of these nodes and form a forest(which is a set of trees). + * @zh RenderGraph中节点的基类,每个RenderGraph节点代表一种渲染操作,并构成一个森林(一组树) + */ class RenderNode { public: RenderNode() noexcept = default; @@ -290,6 +325,10 @@ class RenderNode { RenderNode& operator=(RenderNode const& rhs) = delete; virtual ~RenderNode() noexcept = default; + /** + * @en Get debug name of current node. + * @zh 获得当前节点调试用的名字 + */ virtual ccstd::string getName() const = 0; virtual void setName(const ccstd::string &name) = 0; /** @@ -298,18 +337,82 @@ class RenderNode { virtual void setCustomBehavior(const ccstd::string &name) = 0; }; +/** + * @en Render node which supports setting uniforms and descriptors. + * @zh 节点支持设置常量值(uniform/constant)与描述符 + */ class Setter : public RenderNode { public: Setter() noexcept = default; + /** + * @en Set matrix4x4 常量(uniform) which consists of 16 floats (64 bytes). + * @zh 设置4x4矩阵,常量(uniform)有16个float (64 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setMat4(const ccstd::string &name, const Mat4 &mat) = 0; + /** + * @en Set quaternion uniform which consists of 4 floats (16 bytes). + * @zh 设置四元数向量,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setQuaternion(const ccstd::string &name, const Quaternion &quat) = 0; + /** + * @en Set color uniform which consists of 4 floats (16 bytes). + * @zh 设置颜色值,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setColor(const ccstd::string &name, const gfx::Color &color) = 0; + /** + * @en Set vector4 uniform which consists of 4 floats (16 bytes). + * @zh 设置vector4向量,常量(uniform)有4个float (16 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setVec4(const ccstd::string &name, const Vec4 &vec) = 0; + /** + * @en Set vector2 uniform which consists of 2 floats (8 bytes). + * @zh 设置vector2向量,常量(uniform)有2个float (8 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setVec2(const ccstd::string &name, const Vec2 &vec) = 0; + /** + * @en Set float uniform (4 bytes). + * @zh 设置浮点值 (4 bytes) + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + */ virtual void setFloat(const ccstd::string &name, float v) = 0; + /** + * @en Set uniform array. + * Size and type of the data should match the corresponding uniforms in the shader. + * Mismatches will cause undefined behaviour. + * Memory alignment is not required. + * @zh 设置数组。类型与大小需要与着色器中的常量(uniform)相匹配,不匹配会引起未定义行为。 + * 内存地址不需要对齐。 + * @param name @en uniform name in shader. @zh 填写着色器中的常量(uniform)名字 + * @param arrayBuffer @en array of bytes @zh byte数组 + */ virtual void setArrayBuffer(const ccstd::string &name, const ArrayBuffer *arrayBuffer) = 0; + /** + * @en Set buffer descriptor. + * Size and type of the buffer should match the one in shader. + * Buffer should be in read states and satisfy shader stage visibilities. + * Mismatches will cause undefined behaviour. + * @zh 设置缓冲(buffer)描述符。大小与类型需要与着色器中的一致,处于只读状态且着色阶段可见。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + * @param buffer @en readonly buffer @zh 只读的缓冲 + */ virtual void setBuffer(const ccstd::string &name, gfx::Buffer *buffer) = 0; + /** + * @en Set texture descriptor. + * Type of the texture should match the one in shader. + * Texture should be in read states and satisfy shader stage visibilities. + * Mismatches will cause undefined behaviour. + * @zh 设置贴图描述符。类型需要与着色器中的一致,处于只读状态且着色阶段可见。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + * @param texture @en readonly texture @zh 只读的贴图 + */ virtual void setTexture(const ccstd::string &name, gfx::Texture *texture) = 0; /** * @deprecated Method will be removed in 3.9.0 @@ -319,6 +422,13 @@ class Setter : public RenderNode { * @deprecated Method will be removed in 3.9.0 */ virtual void setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) = 0; + /** + * @en Set sampler descriptor. + * Type of the sampler should match the one in shader. + * @zh 设置采样器描述符。类型需要与着色器中的一致。 + * 不匹配会引起未定义行为。 + * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 + */ virtual void setSampler(const ccstd::string &name, gfx::Sampler *sampler) = 0; }; From dbdce574ddd96b4d1fc9b07259e9549562fcfea6 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 27 Jun 2023 19:03:07 +0800 Subject: [PATCH 29/57] QueueHint updated --- cocos/rendering/custom/pipeline.ts | 118 +++++++++++++++++- cocos/rendering/custom/types.ts | 21 ++-- .../pipeline/custom/RenderCommonNames.h | 6 +- .../pipeline/custom/RenderCommonTypes.h | 9 +- .../pipeline/custom/RenderInterfaceTypes.h | 118 +++++++++++++++++- 5 files changed, 255 insertions(+), 17 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 9ae36fe86c8..427a2abb563 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -241,12 +241,17 @@ export enum SubpassCapabilities { INPUT_COLOR_MRT = 1 << 2, } +/** + * @en Pipeline capabilities. + * The following capabilities are partially supported on different hardware and graphics backends. + * @zh 管线能力。根据硬件与后端,支持的特性会有所不同 + */ export class PipelineCapabilities { subpass: SubpassCapabilities = SubpassCapabilities.NONE; } /** - * @en base class of render graph node. + * @en Base class of render graph node. * A node of render graph represents a specific type of rendering operation. * A render graph consists of these nodes and form a forest(which is a set of trees). * @zh RenderGraph中节点的基类,每个RenderGraph节点代表一种渲染操作,并构成一个森林(一组树) @@ -355,24 +360,63 @@ export interface Setter extends RenderNode { setSampler (name: string, sampler: Sampler): void; } +/** + * @en Render queue + * A render queue is an abstraction of graphics commands submission. + * Only when the graphics commands in a render queue are all submitted, + * the next render queue will start submitting. + * @zh 渲染队列。渲染队列是图形命令提交的抽象。 + * 只有一个渲染队列中的渲染命令全部提交完,才会开始提交下一个渲染队列中的命令。 + */ export interface RenderQueueBuilder extends Setter { /** * @deprecated Method will be removed in 3.9.0 + * @en Render the scene the camera is looking at. + * @zh 渲染当前相机指向的场景。 + * @param camera @en Required camera @zh 所需相机 + * @param light @en Lighting information of the scene @zh 场景光照信息 + * @param sceneFlags @en Rendering flags of the scene @zh 场景渲染标志位 */ addSceneOfCamera ( camera: Camera, light: LightInfo, sceneFlags?: SceneFlags): void; + /** + * @en Render a full-screen quad. + * @zh 渲染全屏四边形 + * @param material @en The material used for shading @zh 着色所需材质 + * @param passID @en Material pass ID @zh 材质通道ID + * @param sceneFlags @en Rendering flags of the quad @zh Quad所需场景渲染标志位 + */ addFullscreenQuad ( material: Material, passID: number, sceneFlags?: SceneFlags): void; + /** + * @en Render a full-screen quad from the camera view. + * @zh 从相机视角渲染全屏四边形 + * @param camera @en The required camera @zh 所需相机 + * @param material @en The material used for shading @zh 着色所需材质 + * @param passID @en Material pass ID @zh 材质通道ID + * @param sceneFlags @en Rendering flags of the quad @zh Quad所需场景渲染标志位 + */ addCameraQuad ( camera: Camera, material: Material, passID: number, sceneFlags?: SceneFlags): void; + /** + * @en Clear current render target. + * @zh 清除当前渲染目标 + * @param name @en The name of the render target @zh 渲染目标的名字 + * @param color @en The clearing color @zh 用来清除与填充的颜色 + */ clearRenderTarget (name: string, color?: Color): void; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ setViewport (viewport: Viewport): void; /** * @experimental @@ -380,12 +424,36 @@ export interface RenderQueueBuilder extends Setter { addCustomCommand (customBehavior: string): void; } +/** + * @en Basic render pass. + * @zh 基础光栅通道 + */ export interface BasicRenderPassBuilder extends Setter { + /** + * @en Add render target for rasterization + * The render target must have registered in pipeline. + * @zh 添加光栅化渲染目标,渲染目标必须已注册。 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param color @en The clear color to use when loadOp is Clear @zh 读取操作为清除时,所用颜色 + */ addRenderTarget ( name: string, loadOp?: LoadOp, storeOp?: StoreOp, color?: Color): void; + /** + * @en Add depth stencil for rasterization + * The depth stencil must have registered in pipeline. + * @zh 添加光栅化深度模板缓冲,深度模板缓冲必须已注册。 + * @param name @en name of the depth stencil @zh 渲染目标的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param depth @en Depth value used to clear @zh 用于清除的深度值 + * @param stencil @en Stencil value used to clear @zh 用于清除的模板值 + * @param clearFlags @en To clear depth, stencil or both @zh 清除分量:深度、模板、两者。 + */ addDepthStencil ( name: string, loadOp?: LoadOp, @@ -393,14 +461,59 @@ export interface BasicRenderPassBuilder extends Setter { depth?: number, stencil?: number, clearFlags?: ClearFlagBit): void; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ addTexture ( name: string, slotName: string, sampler?: Sampler | null, plane?: number): void; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in effect. Default value is 'default' @zh effect中相位(phase)的名字,不填为'default'。 + */ addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ setViewport (viewport: Viewport): void; + /** + * @deprecated Method will be removed in 3.9.0 + */ setVersion (name: string, version: number): void; + /** + * @en show statistics on screen + * @zh 在屏幕上渲染统计数据 + */ showStatistics: boolean; } @@ -456,6 +569,9 @@ export interface BasicPipeline extends PipelineRuntime { count: number, quality: number, passName?: string): BasicRenderPassBuilder; + /** + * @deprecated Method will be removed in 3.9.0 + */ addResolvePass (resolvePairs: ResolvePair[]): void; addCopyPass (copyPairs: CopyPair[]): void; getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout | null; diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index 962f8e9690c..c964335b4ff 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -113,21 +113,24 @@ export function getResourceResidencyName (e: ResourceResidency): string { export enum QueueHint { NONE, - RENDER_OPAQUE, - RENDER_CUTOUT, - RENDER_TRANSPARENT, + OPAQUE, + MASK, + BLEND, + RENDER_OPAQUE = OPAQUE, + RENDER_CUTOUT = MASK, + RENDER_TRANSPARENT = BLEND, } export function getQueueHintName (e: QueueHint): string { switch (e) { case QueueHint.NONE: return 'NONE'; - case QueueHint.RENDER_OPAQUE: - return 'RENDER_OPAQUE'; - case QueueHint.RENDER_CUTOUT: - return 'RENDER_CUTOUT'; - case QueueHint.RENDER_TRANSPARENT: - return 'RENDER_TRANSPARENT'; + case QueueHint.OPAQUE: + return 'OPAQUE'; + case QueueHint.MASK: + return 'MASK'; + case QueueHint.BLEND: + return 'BLEND'; default: return ''; } diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonNames.h b/native/cocos/renderer/pipeline/custom/RenderCommonNames.h index 51a31444204..96624a9700b 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonNames.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonNames.h @@ -77,9 +77,9 @@ inline const char* getName(ResourceResidency e) noexcept { inline const char* getName(QueueHint e) noexcept { switch (e) { case QueueHint::NONE: return "NONE"; - case QueueHint::RENDER_OPAQUE: return "RENDER_OPAQUE"; - case QueueHint::RENDER_CUTOUT: return "RENDER_CUTOUT"; - case QueueHint::RENDER_TRANSPARENT: return "RENDER_TRANSPARENT"; + case QueueHint::OPAQUE: return "OPAQUE"; + case QueueHint::MASK: return "MASK"; + case QueueHint::BLEND: return "BLEND"; } return ""; } diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index ce9584a0c78..fea8e265f87 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -76,9 +76,12 @@ enum class ResourceResidency { enum class QueueHint { NONE, - RENDER_OPAQUE, - RENDER_CUTOUT, - RENDER_TRANSPARENT, + OPAQUE, + MASK, + BLEND, + RENDER_OPAQUE = OPAQUE, + RENDER_CUTOUT = MASK, + RENDER_TRANSPARENT = BLEND, }; enum class ResourceDimension { diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 901bc946ca7..6d976955132 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -306,12 +306,17 @@ constexpr bool any(SubpassCapabilities e) noexcept { return !!e; } +/** + * @en Pipeline capabilities. + * The following capabilities are partially supported on different hardware and graphics backends. + * @zh 管线能力。根据硬件与后端,支持的特性会有所不同 + */ struct PipelineCapabilities { SubpassCapabilities subpass{SubpassCapabilities::NONE}; }; /** - * @en base class of render graph node. + * @en Base class of render graph node. * A node of render graph represents a specific type of rendering operation. * A render graph consists of these nodes and form a forest(which is a set of trees). * @zh RenderGraph中节点的基类,每个RenderGraph节点代表一种渲染操作,并构成一个森林(一组树) @@ -432,17 +437,56 @@ class Setter : public RenderNode { virtual void setSampler(const ccstd::string &name, gfx::Sampler *sampler) = 0; }; +/** + * @en Render queue + * A render queue is an abstraction of graphics commands submission. + * Only when the graphics commands in a render queue are all submitted, + * the next render queue will start submitting. + * @zh 渲染队列。渲染队列是图形命令提交的抽象。 + * 只有一个渲染队列中的渲染命令全部提交完,才会开始提交下一个渲染队列中的命令。 + */ class RenderQueueBuilder : public Setter { public: RenderQueueBuilder() noexcept = default; /** * @deprecated Method will be removed in 3.9.0 + * @en Render the scene the camera is looking at. + * @zh 渲染当前相机指向的场景。 + * @param camera @en Required camera @zh 所需相机 + * @param light @en Lighting information of the scene @zh 场景光照信息 + * @param sceneFlags @en Rendering flags of the scene @zh 场景渲染标志位 */ virtual void addSceneOfCamera(scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) = 0; + /** + * @en Render a full-screen quad. + * @zh 渲染全屏四边形 + * @param material @en The material used for shading @zh 着色所需材质 + * @param passID @en Material pass ID @zh 材质通道ID + * @param sceneFlags @en Rendering flags of the quad @zh Quad所需场景渲染标志位 + */ virtual void addFullscreenQuad(Material *material, uint32_t passID, SceneFlags sceneFlags) = 0; + /** + * @en Render a full-screen quad from the camera view. + * @zh 从相机视角渲染全屏四边形 + * @param camera @en The required camera @zh 所需相机 + * @param material @en The material used for shading @zh 着色所需材质 + * @param passID @en Material pass ID @zh 材质通道ID + * @param sceneFlags @en Rendering flags of the quad @zh Quad所需场景渲染标志位 + */ virtual void addCameraQuad(scene::Camera *camera, Material *material, uint32_t passID, SceneFlags sceneFlags) = 0; + /** + * @en Clear current render target. + * @zh 清除当前渲染目标 + * @param name @en The name of the render target @zh 渲染目标的名字 + * @param color @en The clearing color @zh 用来清除与填充的颜色 + */ virtual void clearRenderTarget(const ccstd::string &name, const gfx::Color &color) = 0; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ virtual void setViewport(const gfx::Viewport &viewport) = 0; /** * @experimental @@ -462,16 +506,85 @@ class RenderQueueBuilder : public Setter { } }; +/** + * @en Basic render pass. + * @zh 基础光栅通道 + */ class BasicRenderPassBuilder : public Setter { public: BasicRenderPassBuilder() noexcept = default; + /** + * @en Add render target for rasterization + * The render target must have registered in pipeline. + * @zh 添加光栅化渲染目标,渲染目标必须已注册。 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param color @en The clear color to use when loadOp is Clear @zh 读取操作为清除时,所用颜色 + */ virtual void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) = 0; + /** + * @en Add depth stencil for rasterization + * The depth stencil must have registered in pipeline. + * @zh 添加光栅化深度模板缓冲,深度模板缓冲必须已注册。 + * @param name @en name of the depth stencil @zh 渲染目标的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param depth @en Depth value used to clear @zh 用于清除的深度值 + * @param stencil @en Stencil value used to clear @zh 用于清除的模板值 + * @param clearFlags @en To clear depth, stencil or both @zh 清除分量:深度、模板、两者。 + */ virtual void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) = 0; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in effect. Default value is 'default' @zh effect中相位(phase)的名字,不填为'default'。 + */ virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ virtual void setViewport(const gfx::Viewport &viewport) = 0; + /** + * @deprecated Method will be removed in 3.9.0 + */ virtual void setVersion(const ccstd::string &name, uint64_t version) = 0; + /** + * @en show statistics on screen + * @zh 在屏幕上渲染统计数据 + */ virtual bool getShowStatistics() const = 0; virtual void setShowStatistics(bool enable) = 0; void addRenderTarget(const ccstd::string &name) { @@ -536,6 +649,9 @@ class BasicPipeline : public PipelineRuntime { virtual void endFrame() = 0; virtual BasicRenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) = 0; virtual BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) = 0; + /** + * @deprecated Method will be removed in 3.9.0 + */ virtual void addResolvePass(const ccstd::vector &resolvePairs) = 0; virtual void addCopyPass(const ccstd::vector ©Pairs) = 0; virtual gfx::DescriptorSetLayout *getDescriptorSetLayout(const ccstd::string &shaderName, UpdateFrequency freq) = 0; From 1da0544dad77768733c31252ce3dc81e89822796 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 28 Jun 2023 13:02:16 +0800 Subject: [PATCH 30/57] Basic Pipeline added --- cocos/rendering/custom/pipeline.ts | 133 +++++++++++++++++- .../pipeline/custom/RenderInterfaceTypes.h | 133 +++++++++++++++++- 2 files changed, 260 insertions(+), 6 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 427a2abb563..bcc9e255dcd 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -497,7 +497,7 @@ export interface BasicRenderPassBuilder extends Setter { * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 * * @param hint @en Usage hint of the queue @zh 用途的提示 - * @param phaseName @en The name of the phase declared in effect. Default value is 'default' @zh effect中相位(phase)的名字,不填为'default'。 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 */ addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; /** @@ -511,7 +511,7 @@ export interface BasicRenderPassBuilder extends Setter { */ setVersion (name: string, version: number): void; /** - * @en show statistics on screen + * @en Show statistics on screen * @zh 在屏幕上渲染统计数据 */ showStatistics: boolean; @@ -519,50 +519,154 @@ export interface BasicRenderPassBuilder extends Setter { /** * @en BasicPipeline - * @zh 基础渲染管线 + * Basic pipeline provides basic rendering features which are supported on all platforms. + * User can register resources which will be used in the render graph. + * Theses resources are generally read and write, and will be managed by the pipeline. + * In each frame, user can create a render graph to be executed by the pipeline. + * @zh 基础渲染管线。 + * 基础渲染管线提供基础的渲染能力,能在全平台使用。 + * 用户可以在渲染管线中注册资源,这些资源将由管线托管,用于render graph。 + * 这些资源一般是可读写的资源。 + * 用户可以每帧构建一个render graph,然后交由管线执行。 */ export interface BasicPipeline extends PipelineRuntime { readonly type: PipelineType; readonly capabilities: PipelineCapabilities; + /** + * @internal + * @en Begin render pipeline setup + * @zh 开始管线构建 + */ beginSetup (): void; + /** + * @internal + * @en End render pipeline setup + * @zh 结束管线构建 + */ endSetup (): void; + /** + * @en Check whether the resource has been registered in the pipeline. + * @zh 检查资源是否在管线中已注册 + * @param name @en Resource name @zh 资源名字 + */ containsResource (name: string): boolean; + /** + * @en Add render window to the pipeline. + * @zh 注册渲染窗口(RenderWindow) + * @param name @en Resource name @zh 资源名字 + * @param format @en Expected format of the render window @zh 期望的渲染窗口格式 + * @param width @en Expected width of the render window @zh 期望的渲染窗口宽度 + * @param height @en Expected height of the render window @zh 期望的渲染窗口高度 + * @param renderWindow @en The render window to add. @zh 需要注册的渲染窗口 + */ addRenderWindow ( name: string, format: Format, width: number, height: number, renderWindow: RenderWindow): number; + /** + * @en Update render window information. + * When render window information is updated, such as resized, user should notify the pipeline. + * @zh 更新渲染窗口信息。当渲染窗口发生更新时,用户应通知管线。 + * @param renderWindow @en The render window to update. @zh 渲染窗口 + */ updateRenderWindow (name: string, renderWindow: RenderWindow): void; + /** + * @en Add 2D render target. + * @zh 添加2D渲染目标 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ addRenderTarget ( name: string, format: Format, width: number, height: number, residency?: ResourceResidency): number; + /** + * @en Add 2D depth stencil. + * @zh 添加2D深度模板缓冲 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ addDepthStencil ( name: string, format: Format, width: number, height: number, residency?: ResourceResidency): number; + /** + * @en Update render target information. + * @zh 更新渲染目标的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ updateRenderTarget ( name: string, width: number, height: number, format?: Format): void; + /** + * @en Update depth stencil information. + * @zh 更新深度模板缓冲的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ updateDepthStencil ( name: string, width: number, height: number, format?: Format): void; + /** + * @internal + * @en Begin rendering one frame + * @zh 开始一帧的渲染 + */ beginFrame (): void; + /** + * @internal + * @en Update camera + * @zh 更新相机 + */ update (camera: Camera): void; + /** + * @internal + * @en End rendering one frame + * @zh 结束一帧的渲染 + */ endFrame (): void; + /** + * @en Add render pass + * @zh 添加渲染通道 + * @param width @en Width of the render pass @zh 渲染通道的宽度 + * @param height @en Height of the render pass @zh 渲染通道的高度 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + */ addRenderPass ( width: number, height: number, passName?: string): BasicRenderPassBuilder; + /** + * @beta Feature is under development + * @en Add multisample render pass + * @zh 添加多重采样渲染通道 + * @param width @en Width of the render pass @zh 渲染通道的宽度 + * @param height @en Height of the render pass @zh 渲染通道的高度 + * @param count @en Sample count @zh 采样数 + * @param quality @en Sample quality. Default value is 0 @zh 采样质量,默认值是0 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + */ addMultisampleRenderPass ( width: number, height: number, @@ -573,7 +677,30 @@ export interface BasicPipeline extends PipelineRuntime { * @deprecated Method will be removed in 3.9.0 */ addResolvePass (resolvePairs: ResolvePair[]): void; + /** + * @en Add copy pass. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * Reinterpret copy is not supported. + * + * @zh 添加拷贝通道,来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * 暂不支持转义拷贝。 + * + * @param copyPairs @en Array of copy source and target pair @zh 拷贝来源与目标的数组 + */ addCopyPass (copyPairs: CopyPair[]): void; + /** + * @internal + */ getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout | null; } diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 6d976955132..d33e85512a7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -568,7 +568,7 @@ class BasicRenderPassBuilder : public Setter { * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 * * @param hint @en Usage hint of the queue @zh 用途的提示 - * @param phaseName @en The name of the phase declared in effect. Default value is 'default' @zh effect中相位(phase)的名字,不填为'default'。 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 */ virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; /** @@ -582,7 +582,7 @@ class BasicRenderPassBuilder : public Setter { */ virtual void setVersion(const ccstd::string &name, uint64_t version) = 0; /** - * @en show statistics on screen + * @en Show statistics on screen * @zh 在屏幕上渲染统计数据 */ virtual bool getShowStatistics() const = 0; @@ -627,7 +627,15 @@ class BasicRenderPassBuilder : public Setter { /** * @en BasicPipeline - * @zh 基础渲染管线 + * Basic pipeline provides basic rendering features which are supported on all platforms. + * User can register resources which will be used in the render graph. + * Theses resources are generally read and write, and will be managed by the pipeline. + * In each frame, user can create a render graph to be executed by the pipeline. + * @zh 基础渲染管线。 + * 基础渲染管线提供基础的渲染能力,能在全平台使用。 + * 用户可以在渲染管线中注册资源,这些资源将由管线托管,用于render graph。 + * 这些资源一般是可读写的资源。 + * 用户可以每帧构建一个render graph,然后交由管线执行。 */ class BasicPipeline : public PipelineRuntime { public: @@ -635,25 +643,144 @@ class BasicPipeline : public PipelineRuntime { virtual PipelineType getType() const = 0; virtual PipelineCapabilities getCapabilities() const = 0; + /** + * @internal + * @en Begin render pipeline setup + * @zh 开始管线构建 + */ virtual void beginSetup() = 0; + /** + * @internal + * @en End render pipeline setup + * @zh 结束管线构建 + */ virtual void endSetup() = 0; + /** + * @en Check whether the resource has been registered in the pipeline. + * @zh 检查资源是否在管线中已注册 + * @param name @en Resource name @zh 资源名字 + */ virtual bool containsResource(const ccstd::string &name) const = 0; + /** + * @en Add render window to the pipeline. + * @zh 注册渲染窗口(RenderWindow) + * @param name @en Resource name @zh 资源名字 + * @param format @en Expected format of the render window @zh 期望的渲染窗口格式 + * @param width @en Expected width of the render window @zh 期望的渲染窗口宽度 + * @param height @en Expected height of the render window @zh 期望的渲染窗口高度 + * @param renderWindow @en The render window to add. @zh 需要注册的渲染窗口 + */ virtual uint32_t addRenderWindow(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) = 0; + /** + * @en Update render window information. + * When render window information is updated, such as resized, user should notify the pipeline. + * @zh 更新渲染窗口信息。当渲染窗口发生更新时,用户应通知管线。 + * @param renderWindow @en The render window to update. @zh 渲染窗口 + */ virtual void updateRenderWindow(const ccstd::string &name, scene::RenderWindow *renderWindow) = 0; + /** + * @en Add 2D render target. + * @zh 添加2D渲染目标 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ virtual uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; + /** + * @en Add 2D depth stencil. + * @zh 添加2D深度模板缓冲 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ virtual uint32_t addDepthStencil(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; + /** + * @en Update render target information. + * @zh 更新渲染目标的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ virtual void updateRenderTarget(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) = 0; + /** + * @en Update depth stencil information. + * @zh 更新深度模板缓冲的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ virtual void updateDepthStencil(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) = 0; + /** + * @internal + * @en Begin rendering one frame + * @zh 开始一帧的渲染 + */ virtual void beginFrame() = 0; + /** + * @internal + * @en Update camera + * @zh 更新相机 + */ virtual void update(const scene::Camera *camera) = 0; + /** + * @internal + * @en End rendering one frame + * @zh 结束一帧的渲染 + */ virtual void endFrame() = 0; + /** + * @en Add render pass + * @zh 添加渲染通道 + * @param width @en Width of the render pass @zh 渲染通道的宽度 + * @param height @en Height of the render pass @zh 渲染通道的高度 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + */ virtual BasicRenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) = 0; + /** + * @beta Feature is under development + * @en Add multisample render pass + * @zh 添加多重采样渲染通道 + * @param width @en Width of the render pass @zh 渲染通道的宽度 + * @param height @en Height of the render pass @zh 渲染通道的高度 + * @param count @en Sample count @zh 采样数 + * @param quality @en Sample quality. Default value is 0 @zh 采样质量,默认值是0 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + */ virtual BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) = 0; /** * @deprecated Method will be removed in 3.9.0 */ virtual void addResolvePass(const ccstd::vector &resolvePairs) = 0; + /** + * @en Add copy pass. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * Reinterpret copy is not supported. + * + * @zh 添加拷贝通道,来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * 暂不支持转义拷贝。 + * + * @param copyPairs @en Array of copy source and target pair @zh 拷贝来源与目标的数组 + */ virtual void addCopyPass(const ccstd::vector ©Pairs) = 0; + /** + * @internal + */ virtual gfx::DescriptorSetLayout *getDescriptorSetLayout(const ccstd::string &shaderName, UpdateFrequency freq) = 0; uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height) { return addRenderTarget(name, format, width, height, ResourceResidency::MANAGED); From 9193c55bffb8694784975dae923044d3d09b9622 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 28 Jun 2023 16:51:08 +0800 Subject: [PATCH 31/57] api documents added --- cocos/rendering/custom/pipeline.ts | 410 +++++++++++++++++- .../pipeline/custom/RenderInterfaceTypes.h | 402 ++++++++++++++++- 2 files changed, 810 insertions(+), 2 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index bcc9e255dcd..1e326ad01bb 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -498,6 +498,7 @@ export interface BasicRenderPassBuilder extends Setter { * * @param hint @en Usage hint of the queue @zh 用途的提示 * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en render queue builder @zh 渲染队列 */ addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; /** @@ -695,7 +696,7 @@ export interface BasicPipeline extends PipelineRuntime { * * 暂不支持转义拷贝。 * - * @param copyPairs @en Array of copy source and target pair @zh 拷贝来源与目标的数组 + * @param copyPairs @en Array of copy source and target @zh 拷贝来源与目标的数组 */ addCopyPass (copyPairs: CopyPair[]): void; /** @@ -704,7 +705,23 @@ export interface BasicPipeline extends PipelineRuntime { getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout | null; } +/** + * @beta Feature is under development + * @en Render subpass + * @zh 渲染次通道 + */ export interface RenderSubpassBuilder extends Setter { + /** + * @en Add render target for rasterization + * The render target must have registered in pipeline. + * @zh 添加光栅化渲染目标,渲染目标必须已注册。 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of the descriptor in shader @zh 着色器中描述符的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param color @en The clear color to use when loadOp is Clear @zh 读取操作为清除时,所用颜色 + */ addRenderTarget ( name: string, accessType: AccessType, @@ -712,6 +729,20 @@ export interface RenderSubpassBuilder extends Setter { loadOp?: LoadOp, storeOp?: StoreOp, color?: Color): void; + /** + * @en Add depth stencil for rasterization + * The depth stencil must have registered in pipeline. + * @zh 添加光栅化深度模板缓冲,深度模板缓冲必须已注册。 + * @param name @en name of the depth stencil @zh 渲染目标的名字 + * @param accessType @en Access type @zh 读写状态 + * @param depthSlotName @en name of the depth descriptor in shader @zh 着色器中深度描述符的名字 + * @param stencilSlotName @en name of the stencil descriptor in shader @zh 着色器中模板描述符的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param depth @en Depth value used to clear @zh 用于清除的深度值 + * @param stencil @en Stencil value used to clear @zh 用于清除的模板值 + * @param clearFlags @en To clear depth, stencil or both @zh 清除分量:深度、模板、两者。 + */ addDepthStencil ( name: string, accessType: AccessType, @@ -722,21 +753,80 @@ export interface RenderSubpassBuilder extends Setter { depth?: number, stencil?: number, clearFlags?: ClearFlagBit): void; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ addTexture ( name: string, slotName: string, sampler?: Sampler | null, plane?: number): void; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageBuffer ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageImage ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ setViewport (viewport: Viewport): void; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en render queue builder @zh 渲染队列 + */ addQueue (hint?: QueueHint, phaseName?: string): RenderQueueBuilder; + /** + * @en Show statistics on screen + * @zh 在屏幕上渲染统计数据 + */ showStatistics: boolean; /** * @experimental @@ -744,8 +834,27 @@ export interface RenderSubpassBuilder extends Setter { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } +/** + * @beta Feature is under development + * @en Multisample render subpass + * @zh 多重采样渲染次通道 + */ export interface MultisampleRenderSubpassBuilder extends RenderSubpassBuilder { + /** + * @en Resolve render target + * @zh 汇总渲染目标 + * @param source @en Multisample source @zh 多重采样来源 + * @param target @en Resolve target @zh 汇总目标 + */ resolveRenderTarget (source: string, target: string): void; + /** + * @en Resolve depth stencil + * @zh 汇总深度模板缓冲 + * @param source @en Multisample source @zh 多重采样来源 + * @param target @en Resolve target @zh 汇总目标 + * @param depthMode @en Resolve mode of depth component @zh 深度分量汇总模式 + * @param stencilMode @en Resolve mode of stencil component @zh 模板分量汇总模式 + */ resolveDepthStencil ( source: string, target: string, @@ -753,7 +862,20 @@ export interface MultisampleRenderSubpassBuilder extends RenderSubpassBuilder { stencilMode?: ResolveMode): void; } +/** + * @en Compute queue + * @zh 计算队列 + */ export interface ComputeQueueBuilder extends Setter { + /** + * @en Dispatch compute task + * @zh 发送计算任务 + * @param threadGroupCountX @en Thread group count X @zh 线程组的X分量的数目 + * @param threadGroupCountY @en Thread group count Y @zh 线程组的Y分量的数目 + * @param threadGroupCountZ @en Thread group count Z @zh 线程组的Z分量的数目 + * @param material @en The material to use @zh 计算任务用的材质 + * @param passID @en The name of the pass declared in the effect. @zh effect中的通道名字 + */ addDispatch ( threadGroupCountX: number, threadGroupCountY: number, @@ -762,21 +884,82 @@ export interface ComputeQueueBuilder extends Setter { passID?: number): void; } +/** + * @beta Feature is under development + * @en Compute subpass + * @zh 计算次通道 + */ export interface ComputeSubpassBuilder extends Setter { + /** + * @en Add input render target. + * @zh 添加输入渲染目标 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param slotName @en name of the descriptor in shader @zh 着色器中描述符的名字 + */ addRenderTarget (name: string, slotName: string): void; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ addTexture ( name: string, slotName: string, sampler?: Sampler | null, plane?: number): void; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageBuffer ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageImage ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en compute queue builder @zh 计算队列 + */ addQueue (phaseName?: string): ComputeQueueBuilder; /** * @experimental @@ -784,11 +967,32 @@ export interface ComputeSubpassBuilder extends Setter { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } +/** + * @beta Feature is under development + * @en Render pass + * @zh 渲染通道 + */ export interface RenderPassBuilder extends BasicRenderPassBuilder { + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageBuffer ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageImage ( name: string, accessType: AccessType, @@ -799,10 +1003,21 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; /** * @beta Feature is under development + * @en Add render subpass. + * @zh 添加渲染次通道 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Render subpass builder */ addRenderSubpass (subpassName: string): RenderSubpassBuilder; /** * @beta Feature is under development + * @en Add multisample render subpass. + * Sample count and quality should match those of the resources. + * @zh 添加多重采样渲染次通道,采样数与质量需要与资源一致。 + * @param count @en Sample count @zh 采样数 + * @param quality @en Sample quality @zh 采样质量 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Multisample render subpass builder */ addMultisampleRenderSubpass ( count: number, @@ -810,6 +1025,10 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { subpassName: string): MultisampleRenderSubpassBuilder; /** * @experimental + * @en Add compute subpass. + * @zh 添加计算次通道 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Compute subpass builder */ addComputeSubpass (subpassName?: string): ComputeSubpassBuilder; /** @@ -818,21 +1037,78 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } +/** + * @en Compute pass + * @zh 计算通道 + */ export interface ComputePassBuilder extends Setter { + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ addTexture ( name: string, slotName: string, sampler?: Sampler | null, plane?: number): void; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageBuffer ( name: string, accessType: AccessType, slotName: string): void; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ addStorageImage ( name: string, accessType: AccessType, slotName: string): void; + /** + * @beta Feature is under development + */ addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit): void; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en compute queue builder @zh 计算队列 + */ addQueue (phaseName?: string): ComputeQueueBuilder; /** * @experimental @@ -840,6 +1116,9 @@ export interface ComputePassBuilder extends Setter { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } +/** + * @deprecated @en Not used @zh 未使用 + */ export interface SceneVisitor { readonly pipelineSceneData: PipelineSceneData; setViewport (vp: Viewport): void; @@ -852,6 +1131,9 @@ export interface SceneVisitor { updateBuffer (buffer: Buffer, data: ArrayBuffer, size?: number): void; } +/** + * @deprecated @en Not used @zh 未使用 + */ export interface SceneTask { readonly taskType: TaskType; start (): void; @@ -859,46 +1141,155 @@ export interface SceneTask { submit (): void; } +/** + * @deprecated @en Not used @zh 未使用 + */ export interface SceneTransversal { transverse (visitor: SceneVisitor): SceneTask; } +/** + * @en Render pipeline. + * @zh 渲染管线 + */ export interface Pipeline extends BasicPipeline { + /** + * @en Add storage buffer. + * @zh 添加存储缓冲 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param size @en Size of the resource @zh 资源的大小 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ addStorageBuffer ( name: string, format: Format, size: number, residency?: ResourceResidency): number; + /** + * @en Add 2D storage texture + * @zh 添加2D存储贴图 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ addStorageTexture ( name: string, format: Format, width: number, height: number, residency?: ResourceResidency): number; + /** + * @experimental + * @en Add 2D shading rate texture + * @zh 添加2D着色率贴图 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ addShadingRateTexture ( name: string, width: number, height: number, residency?: ResourceResidency): number; + /** + * @en Update storage buffer information. + * @zh 更新存储缓冲的信息 + * @param name @en Resource name @zh 资源名字 + * @param size @en Size of the resource @zh 资源的大小 + * @param format @en Format of the resource @zh 资源的格式 + */ updateStorageBuffer ( name: string, size: number, format?: Format): void; + /** + * @en Update storage texture information. + * @zh 更新2D存储贴图的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ updateStorageTexture ( name: string, width: number, height: number, format?: Format): void; + /** + * @en Update shading rate texture information. + * @zh 更新2D着色率贴图的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + */ updateShadingRateTexture ( name: string, width: number, height: number): void; + /** + * @en Add render pass + * @zh 添加渲染通道 + * @param width @en Width of the render pass @zh 渲染通道的宽度 + * @param height @en Height of the render pass @zh 渲染通道的高度 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Render pass builder + */ addRenderPass ( width: number, height: number, passName: string): RenderPassBuilder; + /** + * @en Add compute pass + * @zh 添加计算通道 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Compute pass builder + */ addComputePass (passName: string): ComputePassBuilder; + /** + * @beta Feature is under development + * @en Add upload pass. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * @zh 添加上传通道,来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * @param uploadPairs @en Array of upload source and target @zh 上传来源与目标的数组 + */ addUploadPass (uploadPairs: UploadPair[]): void; + /** + * @en Add move pass. + * Move-construct target resource, by moving source resources into subresources of target. + * After the move, the target resource must be completely initialized. + * Target write conflicts will result in undefined behaviour. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * @zh 添加移动通道。 + * 移动构造目标资源,将来源移入目标的次级资源。 + * 移动后,目标资源必须完全初始化。 + * 目标写入冲突是未定义行为。 + * 来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * @param movePairs @en Array of move source and target @zh 移动来源与目标的数组 + */ addMovePass (movePairs: MovePair[]): void; /** * @experimental @@ -916,10 +1307,27 @@ export interface Pipeline extends BasicPipeline { type: string): number; } +/** + * @en Pipeline builder. + * User can implement this interface and setup render graph. + * Call setCustomPipeline to register the pipeline + * @zh 管线构造器 + * 用户可以实现这个接口,来构建自己想要的render graph。 + * 调用setCustomPipeline注册管线 + */ export interface PipelineBuilder { + /** + * @en Setup render graph + * @zh 构建渲染管线 + * @param cameras @en Camera list to render @zh 需要渲染的相机列表 + * @param pipeline @en Current render pipeline @zh 当前管线 + */ setup (cameras: Camera[], pipeline: BasicPipeline): void; } +/** + * @internal + */ export interface RenderingModule { getPassID (name: string): number; getSubpassID (passID: number, name: string): number; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index d33e85512a7..a3bfccedba6 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -569,6 +569,7 @@ class BasicRenderPassBuilder : public Setter { * * @param hint @en Usage hint of the queue @zh 用途的提示 * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en render queue builder @zh 渲染队列 */ virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; /** @@ -775,7 +776,7 @@ class BasicPipeline : public PipelineRuntime { * * 暂不支持转义拷贝。 * - * @param copyPairs @en Array of copy source and target pair @zh 拷贝来源与目标的数组 + * @param copyPairs @en Array of copy source and target @zh 拷贝来源与目标的数组 */ virtual void addCopyPass(const ccstd::vector ©Pairs) = 0; /** @@ -802,17 +803,106 @@ class BasicPipeline : public PipelineRuntime { } }; +/** + * @beta Feature is under development + * @en Render subpass + * @zh 渲染次通道 + */ class RenderSubpassBuilder : public Setter { public: RenderSubpassBuilder() noexcept = default; + /** + * @en Add render target for rasterization + * The render target must have registered in pipeline. + * @zh 添加光栅化渲染目标,渲染目标必须已注册。 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of the descriptor in shader @zh 着色器中描述符的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param color @en The clear color to use when loadOp is Clear @zh 读取操作为清除时,所用颜色 + */ virtual void addRenderTarget(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) = 0; + /** + * @en Add depth stencil for rasterization + * The depth stencil must have registered in pipeline. + * @zh 添加光栅化深度模板缓冲,深度模板缓冲必须已注册。 + * @param name @en name of the depth stencil @zh 渲染目标的名字 + * @param accessType @en Access type @zh 读写状态 + * @param depthSlotName @en name of the depth descriptor in shader @zh 着色器中深度描述符的名字 + * @param stencilSlotName @en name of the stencil descriptor in shader @zh 着色器中模板描述符的名字 + * @param loadOp @en Type of load operation @zh 读取操作的类型 + * @param storeOp @en Type of store operation @zh 写入操作的类型 + * @param depth @en Depth value used to clear @zh 用于清除的深度值 + * @param stencil @en Stencil value used to clear @zh 用于清除的模板值 + * @param clearFlags @en To clear depth, stencil or both @zh 清除分量:深度、模板、两者。 + */ virtual void addDepthStencil(const ccstd::string &name, AccessType accessType, const ccstd::string &depthSlotName, const ccstd::string &stencilSlotName, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) = 0; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Set rendering viewport. + * @zh 设置渲染视口 + * @param viewport @en The required viewport @zh 所需视口 + */ virtual void setViewport(const gfx::Viewport &viewport) = 0; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en render queue builder @zh 渲染队列 + */ virtual RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) = 0; + /** + * @en Show statistics on screen + * @zh 在屏幕上渲染统计数据 + */ virtual bool getShowStatistics() const = 0; virtual void setShowStatistics(bool enable) = 0; /** @@ -866,11 +956,30 @@ class RenderSubpassBuilder : public Setter { } }; +/** + * @beta Feature is under development + * @en Multisample render subpass + * @zh 多重采样渲染次通道 + */ class MultisampleRenderSubpassBuilder : public RenderSubpassBuilder { public: MultisampleRenderSubpassBuilder() noexcept = default; + /** + * @en Resolve render target + * @zh 汇总渲染目标 + * @param source @en Multisample source @zh 多重采样来源 + * @param target @en Resolve target @zh 汇总目标 + */ virtual void resolveRenderTarget(const ccstd::string &source, const ccstd::string &target) = 0; + /** + * @en Resolve depth stencil + * @zh 汇总深度模板缓冲 + * @param source @en Multisample source @zh 多重采样来源 + * @param target @en Resolve target @zh 汇总目标 + * @param depthMode @en Resolve mode of depth component @zh 深度分量汇总模式 + * @param stencilMode @en Resolve mode of stencil component @zh 模板分量汇总模式 + */ virtual void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target, gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) = 0; void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target) { resolveDepthStencil(source, target, gfx::ResolveMode::SAMPLE_ZERO, gfx::ResolveMode::SAMPLE_ZERO); @@ -880,10 +989,23 @@ class MultisampleRenderSubpassBuilder : public RenderSubpassBuilder { } }; +/** + * @en Compute queue + * @zh 计算队列 + */ class ComputeQueueBuilder : public Setter { public: ComputeQueueBuilder() noexcept = default; + /** + * @en Dispatch compute task + * @zh 发送计算任务 + * @param threadGroupCountX @en Thread group count X @zh 线程组的X分量的数目 + * @param threadGroupCountY @en Thread group count Y @zh 线程组的Y分量的数目 + * @param threadGroupCountZ @en Thread group count Z @zh 线程组的Z分量的数目 + * @param material @en The material to use @zh 计算任务用的材质 + * @param passID @en The name of the pass declared in the effect. @zh effect中的通道名字 + */ virtual void addDispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ, Material *material, uint32_t passID) = 0; void addDispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) { addDispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ, nullptr, 0); @@ -893,14 +1015,75 @@ class ComputeQueueBuilder : public Setter { } }; +/** + * @beta Feature is under development + * @en Compute subpass + * @zh 计算次通道 + */ class ComputeSubpassBuilder : public Setter { public: ComputeSubpassBuilder() noexcept = default; + /** + * @en Add input render target. + * @zh 添加输入渲染目标 + * @param name @en name of the render target @zh 渲染目标的名字 + * @param slotName @en name of the descriptor in shader @zh 着色器中描述符的名字 + */ virtual void addRenderTarget(const ccstd::string &name, const ccstd::string &slotName) = 0; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en compute queue builder @zh 计算队列 + */ virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** * @experimental @@ -917,11 +1100,32 @@ class ComputeSubpassBuilder : public Setter { } }; +/** + * @beta Feature is under development + * @en Render pass + * @zh 渲染通道 + */ class RenderPassBuilder : public BasicRenderPassBuilder { public: RenderPassBuilder() noexcept = default; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; /** * @beta Feature is under development @@ -929,14 +1133,29 @@ class RenderPassBuilder : public BasicRenderPassBuilder { virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; /** * @beta Feature is under development + * @en Add render subpass. + * @zh 添加渲染次通道 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Render subpass builder */ virtual RenderSubpassBuilder *addRenderSubpass(const ccstd::string &subpassName) = 0; /** * @beta Feature is under development + * @en Add multisample render subpass. + * Sample count and quality should match those of the resources. + * @zh 添加多重采样渲染次通道,采样数与质量需要与资源一致。 + * @param count @en Sample count @zh 采样数 + * @param quality @en Sample quality @zh 采样质量 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Multisample render subpass builder */ virtual MultisampleRenderSubpassBuilder *addMultisampleRenderSubpass(uint32_t count, uint32_t quality, const ccstd::string &subpassName) = 0; /** * @experimental + * @en Add compute subpass. + * @zh 添加计算次通道 + * @param subpassName @en Subpass name declared in the effect @zh effect中的subpass name + * @returns Compute subpass builder */ virtual ComputeSubpassBuilder *addComputeSubpass(const ccstd::string &subpassName) = 0; /** @@ -951,14 +1170,71 @@ class RenderPassBuilder : public BasicRenderPassBuilder { } }; +/** + * @en Compute pass + * @zh 计算通道 + */ class ComputePassBuilder : public Setter { public: ComputePassBuilder() noexcept = default; + /** + * @en Add texture for sampling + * The texture must have registered in pipeline. + * @zh 添加采样用的贴图,贴图必须已注册。 + * @param name @en name of the texture @zh 贴图的注册名 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + * @param sampler @en the sampler to use @zh 采样器名字 + * @param plane @en the image plane ID to sample (color|depth|stencil|video) @zh 需要采样的贴图平面(颜色|深度|模板|视频) + */ virtual void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) = 0; + /** + * @en Add storage buffer. + * The buffer must have registered in pipeline. + * @zh 添加存储缓冲,缓冲必须已注册。 + * @param name @en Name of the buffer @zh 缓冲的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @en Add storage texture. + * The texture must have registered in pipeline. + * @zh 添加存储贴图,贴图必须已注册。 + * @param name @en Name of the buffer @zh 贴图的注册名 + * @param accessType @en Access type @zh 读写状态 + * @param slotName @en name of descriptor in the shader @zh 着色器中描述符的名字 + */ virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + /** + * @beta Feature is under development + */ virtual void addMaterialTexture(const ccstd::string &resourceName, gfx::ShaderStageFlagBit flags) = 0; + /** + * @en Add render queue. + * Every render queue has a hint type, such as NONE, OPAQUE, MASK or BLEND. + * User should only add objects of this hint type to the render queue. + * Objects of mixed types might cause downgrading of performance. + * The order of render queues should be adjusted according to the hardward and algorithms, + * in order to reach peak performance. + * For example, [1.opaque, 2.mask, 3.blend] might result in best performance on mobile platforms. + * This hint is for validation only and has no effect on rendering. + * + * Every render queue has a phase name. Only objects of the same phase name will be rendered. + * + * @zh 添加渲染队列 + * 每个渲染队列有一个用途提示,例如无提示(NONE)、不透明(OPAQUE)、遮罩(MASK)和混合(BLEND)。 + * 每个队列最好只渲染相匹配的对象,混合不同类型的对象,会造成性能下降。 + * 不同类型队列的渲染顺序,需要根据硬件类型与渲染算法进行调整,以到达最高性能。 + * 比如在移动平台上,先渲染OPAQUE,再渲染MASK、最后渲染BLEND可能会有最好的性能。 + * 用途提示只用于问题检测,对渲染流程没有任何影响。 + * + * 每个队列有一个相位(phase)名字,具有相同相位名字的物件才会被渲染。 + * + * @param hint @en Usage hint of the queue @zh 用途的提示 + * @param phaseName @en The name of the phase declared in the effect. Default value is 'default' @zh effect中相位(phase)的名字,缺省为'default'。 + * @returns @en compute queue builder @zh 计算队列 + */ virtual ComputeQueueBuilder *addQueue(const ccstd::string &phaseName) = 0; /** * @experimental @@ -978,6 +1254,9 @@ class ComputePassBuilder : public Setter { } }; +/** + * @deprecated @en Not used @zh 未使用 + */ class SceneVisitor { public: SceneVisitor() noexcept = default; @@ -997,6 +1276,9 @@ class SceneVisitor { virtual void draw(const gfx::DrawInfo &info) = 0; }; +/** + * @deprecated @en Not used @zh 未使用 + */ class SceneTask { public: SceneTask() noexcept = default; @@ -1012,6 +1294,9 @@ class SceneTask { virtual void submit() = 0; }; +/** + * @deprecated @en Not used @zh 未使用 + */ class SceneTransversal { public: SceneTransversal() noexcept = default; @@ -1024,19 +1309,117 @@ class SceneTransversal { virtual SceneTask *transverse(SceneVisitor *visitor) const = 0; }; +/** + * @en Render pipeline. + * @zh 渲染管线 + */ class Pipeline : public BasicPipeline { public: Pipeline() noexcept = default; + /** + * @en Add storage buffer. + * @zh 添加存储缓冲 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param size @en Size of the resource @zh 资源的大小 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ virtual uint32_t addStorageBuffer(const ccstd::string &name, gfx::Format format, uint32_t size, ResourceResidency residency) = 0; + /** + * @en Add 2D storage texture + * @zh 添加2D存储贴图 + * @param name @en Resource name @zh 资源名字 + * @param format @en Format of the resource @zh 资源的格式 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ virtual uint32_t addStorageTexture(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; + /** + * @experimental + * @en Add 2D shading rate texture + * @zh 添加2D着色率贴图 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param residency @en Residency of the resource. @zh 资源的驻留性 + */ virtual uint32_t addShadingRateTexture(const ccstd::string &name, uint32_t width, uint32_t height, ResourceResidency residency) = 0; + /** + * @en Update storage buffer information. + * @zh 更新存储缓冲的信息 + * @param name @en Resource name @zh 资源名字 + * @param size @en Size of the resource @zh 资源的大小 + * @param format @en Format of the resource @zh 资源的格式 + */ virtual void updateStorageBuffer(const ccstd::string &name, uint32_t size, gfx::Format format) = 0; + /** + * @en Update storage texture information. + * @zh 更新2D存储贴图的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + * @param format @en Format of the resource @zh 资源的格式 + */ virtual void updateStorageTexture(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) = 0; + /** + * @en Update shading rate texture information. + * @zh 更新2D着色率贴图的信息 + * @param name @en Resource name @zh 资源名字 + * @param width @en Width of the resource @zh 资源的宽度 + * @param height @en Height of the resource @zh 资源的高度 + */ virtual void updateShadingRateTexture(const ccstd::string &name, uint32_t width, uint32_t height) = 0; RenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) override = 0 /* covariant */; + /** + * @en Add compute pass + * @zh 添加计算通道 + * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Compute pass builder + */ virtual ComputePassBuilder *addComputePass(const ccstd::string &passName) = 0; + /** + * @beta Feature is under development + * @en Add upload pass. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * @zh 添加上传通道,来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * @param uploadPairs @en Array of upload source and target @zh 上传来源与目标的数组 + */ virtual void addUploadPass(ccstd::vector &uploadPairs) = 0; + /** + * @en Add move pass. + * Move-construct target resource, by moving source resources into subresources of target. + * After the move, the target resource must be completely initialized. + * Target write conflicts will result in undefined behaviour. + * The source and target resources: + * Must be different resources(have different resource names). + * Must have compatible formats. + * Must have identical dimensions(width, height, depth), sample count and sample quality. + * Can't be currently mapped. + * + * @zh 添加移动通道。 + * 移动构造目标资源,将来源移入目标的次级资源。 + * 移动后,目标资源必须完全初始化。 + * 目标写入冲突是未定义行为。 + * 来源与目标必须满足: + * 是不同的注册资源。 + * 资源格式兼容。 + * 具有相同的尺寸、采样数、采样质量。 + * 不能被Map。 + * + * @param movePairs @en Array of move source and target @zh 移动来源与目标的数组 + */ virtual void addMovePass(const ccstd::vector &movePairs) = 0; /** * @experimental @@ -1063,6 +1446,14 @@ class Pipeline : public BasicPipeline { } }; +/** + * @en Pipeline builder. + * User can implement this interface and setup render graph. + * Call setCustomPipeline to register the pipeline + * @zh 管线构造器 + * 用户可以实现这个接口,来构建自己想要的render graph。 + * 调用setCustomPipeline注册管线 + */ class PipelineBuilder { public: PipelineBuilder() noexcept = default; @@ -1072,9 +1463,18 @@ class PipelineBuilder { PipelineBuilder& operator=(PipelineBuilder const& rhs) = delete; virtual ~PipelineBuilder() noexcept = default; + /** + * @en Setup render graph + * @zh 构建渲染管线 + * @param cameras @en Camera list to render @zh 需要渲染的相机列表 + * @param pipeline @en Current render pipeline @zh 当前管线 + */ virtual void setup(const ccstd::vector &cameras, BasicPipeline *pipeline) = 0; }; +/** + * @internal + */ class RenderingModule { public: RenderingModule() noexcept = default; From 46659835f0ffe0d8b325efba28f43393f0613c2f Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 28 Jun 2023 16:52:37 +0800 Subject: [PATCH 32/57] fix wording --- cocos/rendering/custom/pipeline.ts | 2 +- native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 1e326ad01bb..46f076a692f 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -1310,7 +1310,7 @@ export interface Pipeline extends BasicPipeline { /** * @en Pipeline builder. * User can implement this interface and setup render graph. - * Call setCustomPipeline to register the pipeline + * Call setCustomPipeline to register the pipeline builder * @zh 管线构造器 * 用户可以实现这个接口,来构建自己想要的render graph。 * 调用setCustomPipeline注册管线 diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index a3bfccedba6..ae90ee7ce20 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -1449,7 +1449,7 @@ class Pipeline : public BasicPipeline { /** * @en Pipeline builder. * User can implement this interface and setup render graph. - * Call setCustomPipeline to register the pipeline + * Call setCustomPipeline to register the pipeline builder * @zh 管线构造器 * 用户可以实现这个接口,来构建自己想要的render graph。 * 调用setCustomPipeline注册管线 From a632a47d40f64f8c57b0d99a3d3502e439b46865 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 29 Jun 2023 11:30:48 +0800 Subject: [PATCH 33/57] update doc --- cocos/rendering/custom/pipeline.ts | 33 ++++++++++++++----- .../pipeline/custom/RenderInterfaceTypes.h | 33 ++++++++++++++----- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 46f076a692f..7bdabfe1981 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -41,7 +41,7 @@ import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; /** - * @internal + * @engineInternal * @en PipelineRuntime is the runtime of both classical and custom pipelines. * It is used internally and should not be called directly. * @zh PipelineRuntime是经典管线以及自定义管线的运行时。 @@ -51,16 +51,20 @@ export interface PipelineRuntime { /** * @en Activate PipelineRuntime with default swapchain * @zh 用默认交换链初始化PipelineRuntime + * @param swapchain @en Default swapchain @zh 默认的交换链 + * @returns Success or not */ activate (swapchain: Swapchain): boolean; /** * @en Destroy resources of PipelineRuntime * @zh 销毁PipelineRuntime所持资源 + * @returns Success or not */ destroy (): boolean; /** * @en Render contents of cameras * @zh 根据相机进行绘制 + * @param cameras @en Camera list @zh 相机列表 */ render (cameras: Camera[]): void; /** @@ -127,36 +131,42 @@ export interface PipelineRuntime { * @en Get macro as string. * @zh 根据宏名获得字符串 * @param name @en Name of macro @zh 宏的名字 + * @returns String value */ getMacroString (name: string): string; /** * @en Get macro as integer. * @zh 根据宏名获得整型 * @param name @en Name of macro @zh 宏的名字 + * @returns Integer value */ getMacroInt (name: string): number; /** * @en Get macro as boolean. * @zh 根据宏名获得布尔值 * @param name @en Name of macro @zh 宏的名字 + * @returns Boolean value */ getMacroBool (name: string): boolean; /** * @en Assign string value to macro. * @zh 给宏赋值字符串 * @param name @en Name of macro @zh 宏的名字 + * @param value @en String value @zh 字符串 */ setMacroString (name: string, value: string): void; /** * @en Assign integer value to macro. * @zh 给宏赋值整型 * @param name @en Name of macro @zh 宏的名字 + * @param value @en Integer value @zh 整型值 */ setMacroInt (name: string, value: number): void; /** * @en Assign boolean value to macro. * @zh 给宏赋值布尔值 * @param name @en Name of macro @zh 宏的名字 + * @param value @en Boolean value @zh 布尔值 */ setMacroBool (name: string, value: boolean): void; /** @@ -534,13 +544,13 @@ export interface BasicPipeline extends PipelineRuntime { readonly type: PipelineType; readonly capabilities: PipelineCapabilities; /** - * @internal + * @engineInternal * @en Begin render pipeline setup * @zh 开始管线构建 */ beginSetup (): void; /** - * @internal + * @engineInternal * @en End render pipeline setup * @zh 结束管线构建 */ @@ -549,6 +559,7 @@ export interface BasicPipeline extends PipelineRuntime { * @en Check whether the resource has been registered in the pipeline. * @zh 检查资源是否在管线中已注册 * @param name @en Resource name @zh 资源名字 + * @returns Exist or not */ containsResource (name: string): boolean; /** @@ -559,6 +570,7 @@ export interface BasicPipeline extends PipelineRuntime { * @param width @en Expected width of the render window @zh 期望的渲染窗口宽度 * @param height @en Expected height of the render window @zh 期望的渲染窗口高度 * @param renderWindow @en The render window to add. @zh 需要注册的渲染窗口 + * @returns Resource ID */ addRenderWindow ( name: string, @@ -581,6 +593,7 @@ export interface BasicPipeline extends PipelineRuntime { * @param width @en Width of the resource @zh 资源的宽度 * @param height @en Height of the resource @zh 资源的高度 * @param residency @en Residency of the resource. @zh 资源的驻留性 + * @returns Resource ID */ addRenderTarget ( name: string, @@ -596,6 +609,7 @@ export interface BasicPipeline extends PipelineRuntime { * @param width @en Width of the resource @zh 资源的宽度 * @param height @en Height of the resource @zh 资源的高度 * @param residency @en Residency of the resource. @zh 资源的驻留性 + * @returns Resource ID */ addDepthStencil ( name: string, @@ -630,19 +644,20 @@ export interface BasicPipeline extends PipelineRuntime { height: number, format?: Format): void; /** - * @internal + * @engineInternal * @en Begin rendering one frame * @zh 开始一帧的渲染 */ beginFrame (): void; /** - * @internal + * @engineInternal * @en Update camera * @zh 更新相机 + * @param camera @en Camera @zh 相机 */ update (camera: Camera): void; /** - * @internal + * @engineInternal * @en End rendering one frame * @zh 结束一帧的渲染 */ @@ -653,6 +668,7 @@ export interface BasicPipeline extends PipelineRuntime { * @param width @en Width of the render pass @zh 渲染通道的宽度 * @param height @en Height of the render pass @zh 渲染通道的高度 * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Basic render pass builder */ addRenderPass ( width: number, @@ -667,6 +683,7 @@ export interface BasicPipeline extends PipelineRuntime { * @param count @en Sample count @zh 采样数 * @param quality @en Sample quality. Default value is 0 @zh 采样质量,默认值是0 * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Multisample basic render pass builder */ addMultisampleRenderPass ( width: number, @@ -700,7 +717,7 @@ export interface BasicPipeline extends PipelineRuntime { */ addCopyPass (copyPairs: CopyPair[]): void; /** - * @internal + * @engineInternal */ getDescriptorSetLayout (shaderName: string, freq: UpdateFrequency): DescriptorSetLayout | null; } @@ -1326,7 +1343,7 @@ export interface PipelineBuilder { } /** - * @internal + * @engineInternal */ export interface RenderingModule { getPassID (name: string): number; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index ae90ee7ce20..3a2d25b3a39 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -78,7 +78,7 @@ namespace cc { namespace render { /** - * @internal + * @engineInternal * @en PipelineRuntime is the runtime of both classical and custom pipelines. * It is used internally and should not be called directly. * @zh PipelineRuntime是经典管线以及自定义管线的运行时。 @@ -96,16 +96,20 @@ class PipelineRuntime { /** * @en Activate PipelineRuntime with default swapchain * @zh 用默认交换链初始化PipelineRuntime + * @param swapchain @en Default swapchain @zh 默认的交换链 + * @returns Success or not */ virtual bool activate(gfx::Swapchain *swapchain) = 0; /** * @en Destroy resources of PipelineRuntime * @zh 销毁PipelineRuntime所持资源 + * @returns Success or not */ virtual bool destroy() noexcept = 0; /** * @en Render contents of cameras * @zh 根据相机进行绘制 + * @param cameras @en Camera list @zh 相机列表 */ virtual void render(const ccstd::vector &cameras) = 0; /** @@ -174,36 +178,42 @@ class PipelineRuntime { * @en Get macro as string. * @zh 根据宏名获得字符串 * @param name @en Name of macro @zh 宏的名字 + * @returns String value */ virtual const ccstd::string &getMacroString(const ccstd::string &name) const = 0; /** * @en Get macro as integer. * @zh 根据宏名获得整型 * @param name @en Name of macro @zh 宏的名字 + * @returns Integer value */ virtual int32_t getMacroInt(const ccstd::string &name) const = 0; /** * @en Get macro as boolean. * @zh 根据宏名获得布尔值 * @param name @en Name of macro @zh 宏的名字 + * @returns Boolean value */ virtual bool getMacroBool(const ccstd::string &name) const = 0; /** * @en Assign string value to macro. * @zh 给宏赋值字符串 * @param name @en Name of macro @zh 宏的名字 + * @param value @en String value @zh 字符串 */ virtual void setMacroString(const ccstd::string &name, const ccstd::string &value) = 0; /** * @en Assign integer value to macro. * @zh 给宏赋值整型 * @param name @en Name of macro @zh 宏的名字 + * @param value @en Integer value @zh 整型值 */ virtual void setMacroInt(const ccstd::string &name, int32_t value) = 0; /** * @en Assign boolean value to macro. * @zh 给宏赋值布尔值 * @param name @en Name of macro @zh 宏的名字 + * @param value @en Boolean value @zh 布尔值 */ virtual void setMacroBool(const ccstd::string &name, bool value) = 0; /** @@ -645,13 +655,13 @@ class BasicPipeline : public PipelineRuntime { virtual PipelineType getType() const = 0; virtual PipelineCapabilities getCapabilities() const = 0; /** - * @internal + * @engineInternal * @en Begin render pipeline setup * @zh 开始管线构建 */ virtual void beginSetup() = 0; /** - * @internal + * @engineInternal * @en End render pipeline setup * @zh 结束管线构建 */ @@ -660,6 +670,7 @@ class BasicPipeline : public PipelineRuntime { * @en Check whether the resource has been registered in the pipeline. * @zh 检查资源是否在管线中已注册 * @param name @en Resource name @zh 资源名字 + * @returns Exist or not */ virtual bool containsResource(const ccstd::string &name) const = 0; /** @@ -670,6 +681,7 @@ class BasicPipeline : public PipelineRuntime { * @param width @en Expected width of the render window @zh 期望的渲染窗口宽度 * @param height @en Expected height of the render window @zh 期望的渲染窗口高度 * @param renderWindow @en The render window to add. @zh 需要注册的渲染窗口 + * @returns Resource ID */ virtual uint32_t addRenderWindow(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, scene::RenderWindow *renderWindow) = 0; /** @@ -687,6 +699,7 @@ class BasicPipeline : public PipelineRuntime { * @param width @en Width of the resource @zh 资源的宽度 * @param height @en Height of the resource @zh 资源的高度 * @param residency @en Residency of the resource. @zh 资源的驻留性 + * @returns Resource ID */ virtual uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; /** @@ -697,6 +710,7 @@ class BasicPipeline : public PipelineRuntime { * @param width @en Width of the resource @zh 资源的宽度 * @param height @en Height of the resource @zh 资源的高度 * @param residency @en Residency of the resource. @zh 资源的驻留性 + * @returns Resource ID */ virtual uint32_t addDepthStencil(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) = 0; /** @@ -718,19 +732,20 @@ class BasicPipeline : public PipelineRuntime { */ virtual void updateDepthStencil(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) = 0; /** - * @internal + * @engineInternal * @en Begin rendering one frame * @zh 开始一帧的渲染 */ virtual void beginFrame() = 0; /** - * @internal + * @engineInternal * @en Update camera * @zh 更新相机 + * @param camera @en Camera @zh 相机 */ virtual void update(const scene::Camera *camera) = 0; /** - * @internal + * @engineInternal * @en End rendering one frame * @zh 结束一帧的渲染 */ @@ -741,6 +756,7 @@ class BasicPipeline : public PipelineRuntime { * @param width @en Width of the render pass @zh 渲染通道的宽度 * @param height @en Height of the render pass @zh 渲染通道的高度 * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Basic render pass builder */ virtual BasicRenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) = 0; /** @@ -752,6 +768,7 @@ class BasicPipeline : public PipelineRuntime { * @param count @en Sample count @zh 采样数 * @param quality @en Sample quality. Default value is 0 @zh 采样质量,默认值是0 * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' + * @returns Multisample basic render pass builder */ virtual BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) = 0; /** @@ -780,7 +797,7 @@ class BasicPipeline : public PipelineRuntime { */ virtual void addCopyPass(const ccstd::vector ©Pairs) = 0; /** - * @internal + * @engineInternal */ virtual gfx::DescriptorSetLayout *getDescriptorSetLayout(const ccstd::string &shaderName, UpdateFrequency freq) = 0; uint32_t addRenderTarget(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height) { @@ -1473,7 +1490,7 @@ class PipelineBuilder { }; /** - * @internal + * @engineInternal */ class RenderingModule { public: From 9be4bd7e6d3d48d07541783fa59457ce42a781ed Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 29 Jun 2023 18:58:12 +0800 Subject: [PATCH 34/57] add multisample render pass builder --- cocos/rendering/custom/pipeline.ts | 16 +- cocos/rendering/custom/web-pipeline.ts | 21 +- native/CMakeLists.txt | 1 + .../pipeline/custom/NativePipeline.cpp | 75 ++-- .../pipeline/custom/NativePipelineFwd.h | 1 + .../pipeline/custom/NativePipelineTypes.h | 72 +++- .../pipeline/custom/NativeRenderGraph.cpp | 331 ++++++++++-------- .../pipeline/custom/NativeRenderGraphUtils.h | 164 +++++++++ .../pipeline/custom/RenderInterfaceFwd.h | 1 + .../pipeline/custom/RenderInterfaceTypes.h | 23 +- 10 files changed, 506 insertions(+), 199 deletions(-) create mode 100644 native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 7bdabfe1981..688724a4c0b 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -249,6 +249,11 @@ export enum SubpassCapabilities { * @zh 支持读取当前像素任意颜色值 */ INPUT_COLOR_MRT = 1 << 2, + /** + * @en Each subpass has its own sample count. + * @zh 每个Subpass拥有不同的采样数 + */ + HETEROGENEOUS_SAMPLE_COUNT = 1 << 3, } /** @@ -528,6 +533,15 @@ export interface BasicRenderPassBuilder extends Setter { showStatistics: boolean; } +export interface BasicMultisampleRenderPassBuilder extends BasicRenderPassBuilder { + resolveRenderTarget (source: string, target: string): void; + resolveDepthStencil ( + source: string, + target: string, + depthMode?: ResolveMode, + stencilMode?: ResolveMode): void; +} + /** * @en BasicPipeline * Basic pipeline provides basic rendering features which are supported on all platforms. @@ -690,7 +704,7 @@ export interface BasicPipeline extends PipelineRuntime { height: number, count: number, quality: number, - passName?: string): BasicRenderPassBuilder; + passName?: string): BasicMultisampleRenderPassBuilder; /** * @deprecated Method will be removed in 3.9.0 */ diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 68bc6b28d68..d1209fcdb22 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -25,11 +25,11 @@ /* eslint-disable max-len */ import { systemInfo } from 'pal/system-info'; import { DEBUG } from 'internal:constants'; -import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo } from '../../gfx'; +import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, ResolveMode } from '../../gfx'; import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy } from '../../core'; import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; -import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities } from './pipeline'; +import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities, BasicMultisampleRenderPassBuilder } from './pipeline'; import { PipelineSceneData } from '../pipeline-scene-data'; import { Model, Camera, ShadowType, CSMLevel, DirectionalLight, SpotLight, PCFType, Shadows } from '../../render-scene/scene'; import { Light, LightType } from '../../render-scene/scene/light'; @@ -970,7 +970,7 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB private readonly _layoutGraph: LayoutGraphData; } -export class WebRenderPassBuilder extends WebSetter implements BasicRenderPassBuilder { +export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleRenderPassBuilder { constructor (data: RenderData, renderGraph: RenderGraph, layoutGraph: LayoutGraphData, resourceGraph: ResourceGraph, vertID: number, pass: RasterPass, pipeline: PipelineSceneData) { super(data, layoutGraph); this._renderGraph = renderGraph; @@ -1028,6 +1028,17 @@ export class WebRenderPassBuilder extends WebSetter implements BasicRenderPassBu clearFlag, new Color(depth, stencil, 0, 0)); this._pass.rasterViews.set(name, view); + } + resolveRenderTarget (source: string, target: string): void { + + } + resolveDepthStencil ( + source: string, + target: string, + depthMode?: ResolveMode, + stencilMode?: ResolveMode, + ): void { + } private _addComputeResource (name: string, accessType: AccessType, slotName: string) { const view = new ComputeView(slotName); @@ -1762,7 +1773,7 @@ export class WebPipeline implements BasicPipeline { this.execute(); this.endFrame(); } - addRenderPassImpl (width: number, height: number, layoutName: string, count = 1, quality = 0): BasicRenderPassBuilder { + addRenderPassImpl (width: number, height: number, layoutName: string, count = 1, quality = 0): BasicMultisampleRenderPassBuilder { if (DEBUG) { const stageId = this.layoutGraph.locateChild(this.layoutGraph.nullVertex(), layoutName); assert(stageId !== 0xFFFFFFFF); @@ -1789,7 +1800,7 @@ export class WebPipeline implements BasicPipeline { addRenderPass (width: number, height: number, layoutName = 'default'): BasicRenderPassBuilder { return this.addRenderPassImpl(width, height, layoutName); } - addMultisampleRenderPass (width: number, height: number, count: number, quality: number, layoutName = 'default'): BasicRenderPassBuilder { + addMultisampleRenderPass (width: number, height: number, count: number, quality: number, layoutName = 'default'): BasicMultisampleRenderPassBuilder { assert(count > 1); return this.addRenderPassImpl(width, height, layoutName, count, quality); } diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index f480b129c88..8118c07d256 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -1422,6 +1422,7 @@ cocos_source_files( cocos/renderer/pipeline/custom/NativePools.cpp cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp cocos/renderer/pipeline/custom/NativeRenderGraph.cpp + cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h cocos/renderer/pipeline/custom/NativeRenderQueue.cpp cocos/renderer/pipeline/custom/NativeRenderingModule.cpp cocos/renderer/pipeline/custom/NativeResourceGraph.cpp diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index c29c794f708..a6cae32f6df 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -31,6 +31,7 @@ #include "LayoutGraphUtils.h" #include "NativePipelineFwd.h" #include "NativePipelineTypes.h" +#include "NativeRenderGraphUtils.h" #include "NativeUtils.h" #include "RenderCommonTypes.h" #include "RenderGraphGraphs.h" @@ -504,6 +505,7 @@ void NativePipeline::updateShadingRateTexture( } void NativePipeline::beginFrame() { + // noop } void NativePipeline::update(const scene::Camera *camera) { @@ -516,59 +518,52 @@ void NativePipeline::update(const scene::Camera *camera) { } void NativePipeline::endFrame() { + // noop } -namespace { - -RenderPassBuilder *addRenderPassImpl( - const PipelineRuntime *ppl, - RenderGraph &renderGraph, const NativeProgramLibrary &lib, - uint32_t width, uint32_t height, // NOLINT(bugprone-easily-swappable-parameters) - uint32_t count, uint32_t quality, // NOLINT(bugprone-easily-swappable-parameters) +RenderPassBuilder *NativePipeline::addRenderPass( + uint32_t width, uint32_t height, const ccstd::string &passName) { - RasterPass pass(renderGraph.get_allocator()); - pass.width = width; - pass.height = height; - pass.viewport.width = width; - pass.viewport.height = height; - pass.count = count; - pass.quality = quality; - - auto passID = addVertex( - RasterPassTag{}, - std::forward_as_tuple(passName), - std::forward_as_tuple(passName), - std::forward_as_tuple(), - std::forward_as_tuple(), - std::forward_as_tuple(std::move(pass)), - renderGraph); + const auto &layoutGraph = programLibrary->layoutGraph; - auto passLayoutID = locate(LayoutGraphData::null_vertex(), passName, lib.layoutGraph); - CC_EXPECTS(passLayoutID != LayoutGraphData::null_vertex()); + auto [passID, passLayoutID] = addRenderPassVertex( + renderGraph, layoutGraph, + width, height, 1, 0, passName); auto *builder = ccnew NativeRenderPassBuilder( - ppl, &renderGraph, passID, &lib.layoutGraph, passLayoutID); + this, &renderGraph, passID, &layoutGraph, passLayoutID); + updateRasterPassConstants(width, height, *builder); return builder; } -} // namespace - -RenderPassBuilder *NativePipeline::addRenderPass( - uint32_t width, uint32_t height, // NOLINT(bugprone-easily-swappable-parameters) - const ccstd::string &passName) { - return addRenderPassImpl( - this, renderGraph, *programLibrary, width, height, 1, 0, passName); -} - -BasicRenderPassBuilder *NativePipeline::addMultisampleRenderPass( - uint32_t width, uint32_t height, // NOLINT(bugprone-easily-swappable-parameters) +BasicMultisampleRenderPassBuilder *NativePipeline::addMultisampleRenderPass( + uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) { CC_EXPECTS(count > 1); - return addRenderPassImpl( - this, renderGraph, *programLibrary, width, height, count, quality, passName); + const auto &layoutGraph = programLibrary->layoutGraph; + + auto [passID, passLayoutID] = addRenderPassVertex( + renderGraph, layoutGraph, + width, height, count, quality, passName); + + auto &pass = get(RasterPassTag{}, passID, renderGraph); + + auto [subpassID, subpassLayoutID] = addRenderSubpassVertex( + pass, renderGraph, passID, + layoutGraph, passLayoutID, + "", // subpassName is empty + count, quality); + + auto *builder = ccnew NativeBasicMultisampleRenderPassBuilder( + this, &renderGraph, passID, &layoutGraph, passLayoutID, + subpassID, subpassLayoutID); + + updateRasterPassConstants(pass.width, pass.height, *builder); + + return builder; } void NativePipeline::addResolvePass(const ccstd::vector &resolvePairs) { @@ -743,7 +738,7 @@ bool NativePipeline::activate(gfx::Swapchain *swapchainIn) { setValue("CC_USE_HDR", getPipelineSceneData()->isHDR()); #if ENABLE_FLOAT_OUTPUT setValue("CC_USE_FLOAT_OUTPUT", true); -# else +#else setValue("CC_USE_FLOAT_OUTPUT", false); #endif diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h index 13635e3aff2..c4a04781c12 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h @@ -46,6 +46,7 @@ class NativeRenderSubpassBuilder; class NativeMultisampleRenderSubpassBuilder; class NativeComputeSubpassBuilder; class NativeRenderPassBuilder; +class NativeBasicMultisampleRenderPassBuilder; class NativeComputeQueueBuilder; class NativeComputePassBuilder; class NativeSceneTransversal; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index b2b8aa64065..70d6435b83c 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -475,6 +475,76 @@ class NativeRenderPassBuilder final : public RenderPassBuilder, public NativeSet void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) override; }; +class NativeBasicMultisampleRenderPassBuilder final : public BasicMultisampleRenderPassBuilder, public NativeSetter { +public: + NativeBasicMultisampleRenderPassBuilder(const PipelineRuntime* pipelineRuntimeIn, RenderGraph* renderGraphIn, uint32_t nodeIDIn, const LayoutGraphData* layoutGraphIn, uint32_t layoutIDIn, uint32_t subpassIDIn, uint32_t subpassLayoutIDIn) noexcept // NOLINT + : NativeSetter(pipelineRuntimeIn, renderGraphIn, nodeIDIn, layoutGraphIn, layoutIDIn), + subpassID(subpassIDIn), + subpassLayoutID(subpassLayoutIDIn) {} + + ccstd::string getName() const override { + return NativeRenderNode::getName(); + } + void setName(const ccstd::string &name) override { + NativeRenderNode::setName(name); + } + void setCustomBehavior(const ccstd::string &name) override { + NativeRenderNode::setCustomBehavior(name); + } + + void setMat4(const ccstd::string &name, const Mat4 &mat) override { + NativeSetter::setMat4(name, mat); + } + void setQuaternion(const ccstd::string &name, const Quaternion &quat) override { + NativeSetter::setQuaternion(name, quat); + } + void setColor(const ccstd::string &name, const gfx::Color &color) override { + NativeSetter::setColor(name, color); + } + void setVec4(const ccstd::string &name, const Vec4 &vec) override { + NativeSetter::setVec4(name, vec); + } + void setVec2(const ccstd::string &name, const Vec2 &vec) override { + NativeSetter::setVec2(name, vec); + } + void setFloat(const ccstd::string &name, float v) override { + NativeSetter::setFloat(name, v); + } + void setArrayBuffer(const ccstd::string &name, const ArrayBuffer *arrayBuffer) override { + NativeSetter::setArrayBuffer(name, arrayBuffer); + } + void setBuffer(const ccstd::string &name, gfx::Buffer *buffer) override { + NativeSetter::setBuffer(name, buffer); + } + void setTexture(const ccstd::string &name, gfx::Texture *texture) override { + NativeSetter::setTexture(name, texture); + } + void setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) override { + NativeSetter::setReadWriteBuffer(name, buffer); + } + void setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) override { + NativeSetter::setReadWriteTexture(name, texture); + } + void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { + NativeSetter::setSampler(name, sampler); + } + + void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override; + void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) override; + void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) override; + RenderQueueBuilder *addQueue(QueueHint hint, const ccstd::string &phaseName) override; + void setViewport(const gfx::Viewport &viewport) override; + void setVersion(const ccstd::string &name, uint64_t version) override; + bool getShowStatistics() const override; + void setShowStatistics(bool enable) override; + + void resolveRenderTarget(const ccstd::string &source, const ccstd::string &target) override; + void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target, gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) override; + + uint32_t subpassID{RenderGraph::null_vertex()}; + uint32_t subpassLayoutID{RenderGraph::null_vertex()}; +}; + class NativeComputeQueueBuilder final : public ComputeQueueBuilder, public NativeSetter { public: NativeComputeQueueBuilder(const PipelineRuntime* pipelineRuntimeIn, RenderGraph* renderGraphIn, uint32_t nodeIDIn, const LayoutGraphData* layoutGraphIn, uint32_t layoutIDIn) noexcept @@ -1109,7 +1179,7 @@ class NativePipeline final : public Pipeline { void beginFrame() override; void update(const scene::Camera *camera) override; void endFrame() override; - BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) override; + BasicMultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) override; void addResolvePass(const ccstd::vector &resolvePairs) override; void addCopyPass(const ccstd::vector ©Pairs) override; gfx::DescriptorSetLayout *getDescriptorSetLayout(const ccstd::string &shaderName, UpdateFrequency freq) override; diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 323f1253c31..4f318d74a96 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -27,6 +27,7 @@ #include "LayoutGraphGraphs.h" #include "NativePipelineGraphs.h" #include "NativePipelineTypes.h" +#include "NativeRenderGraphUtils.h" #include "NativeUtils.h" #include "RenderCommonNames.h" #include "RenderCommonTypes.h" @@ -466,105 +467,14 @@ void NativeRenderPassBuilder::addDepthStencil( stencil); } -namespace { - -void addComputeView(NativeRenderPassBuilder &builder, const ccstd::string &name, const ComputeView &view) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &pass = get(RasterPassTag{}, builder.nodeID, *builder.renderGraph); - auto iter = pass.computeViews.find(name.c_str()); - if (iter == pass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = pass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); -} - -void addComputeView(NativeComputePassBuilder &builder, const ccstd::string &name, const ComputeView &view) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &pass = get(ComputeTag{}, builder.nodeID, *builder.renderGraph); - auto iter = pass.computeViews.find(name.c_str()); - if (iter == pass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = pass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); -} - -template -void addComputeViewImpl( - const ccstd::string &name, const ComputeView &view, - RenderGraph::vertex_descriptor subpassID, - RenderGraph &renderGraph) { - CC_EXPECTS(!name.empty()); - CC_EXPECTS(!view.name.empty()); - auto &subpass = get(Tag{}, subpassID, renderGraph); - const auto passID = parent(subpassID, renderGraph); - CC_EXPECTS(passID != RenderGraph::null_vertex()); - CC_EXPECTS(holds(passID, renderGraph)); - auto &pass = get(RasterPassTag{}, passID, renderGraph); - CC_EXPECTS(subpass.subpassID < num_vertices(pass.subpassGraph)); - auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); - CC_EXPECTS(subpass.computeViews.size() == subpassData.computeViews.size()); - { - auto iter = subpassData.computeViews.find(name.c_str()); - if (iter == subpassData.computeViews.end()) { - bool added = false; - std::tie(iter, added) = subpassData.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); - } - { - auto iter = subpass.computeViews.find(name.c_str()); - if (iter == subpass.computeViews.end()) { - bool added = false; - std::tie(iter, added) = subpass.computeViews.emplace( - std::piecewise_construct, - std::forward_as_tuple(name.c_str()), - std::forward_as_tuple()); - CC_ENSURES(added); - } - iter->second.emplace_back(view); - } - CC_ENSURES(subpass.computeViews.size() == subpassData.computeViews.size()); - CC_ENSURES(subpass.computeViews.find(std::string_view{name}) != subpass.computeViews.end()); - CC_ENSURES(subpassData.computeViews.find(std::string_view{name}) != subpassData.computeViews.end()); - CC_ENSURES(subpass.computeViews.find(std::string_view{name})->second.size() == - subpassData.computeViews.find(std::string_view{name})->second.size()); -} - -void addComputeView( - NativeRenderSubpassBuilderImpl &builder, - const ccstd::string &name, const ComputeView &view) { - addComputeViewImpl(name, view, builder.nodeID, *builder.renderGraph); -} - -void addComputeView( - NativeComputeSubpassBuilder &builder, const ccstd::string &name, const ComputeView &view) { - addComputeViewImpl(name, view, builder.nodeID, *builder.renderGraph); -} - -} // namespace - // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) void NativeRenderPassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - addComputeView( - *this, + addPassComputeViewImpl( + RasterPassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -586,8 +496,10 @@ void NativeRenderPassBuilder::addTexture( void NativeRenderPassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addPassComputeViewImpl( + RasterPassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -601,8 +513,10 @@ void NativeRenderPassBuilder::addStorageBuffer( void NativeRenderPassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addPassComputeViewImpl( + RasterPassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -768,8 +682,10 @@ void NativeRenderSubpassBuilderImpl::addDepthStencil( void NativeRenderSubpassBuilderImpl::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - addComputeView( - *this, + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -791,8 +707,10 @@ void NativeRenderSubpassBuilderImpl::addTexture( void NativeRenderSubpassBuilderImpl::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -806,8 +724,10 @@ void NativeRenderSubpassBuilderImpl::addStorageBuffer( void NativeRenderSubpassBuilderImpl::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -958,8 +878,10 @@ void NativeComputeSubpassBuilder::addRenderTarget(const ccstd::string &name, con void NativeComputeSubpassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - addComputeView( - *this, + addSubpassComputeViewImpl( + ComputeSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -981,8 +903,10 @@ void NativeComputeSubpassBuilder::addTexture( void NativeComputeSubpassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addSubpassComputeViewImpl( + ComputeSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -996,8 +920,10 @@ void NativeComputeSubpassBuilder::addStorageBuffer( void NativeComputeSubpassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addSubpassComputeViewImpl( + ComputeSubpassTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1166,7 +1092,7 @@ float getPCFRadius( case scene::PCFType::SOFT_2X: return 2.0F / (shadowMapSize * 0.5F); case scene::PCFType::SOFT_4X: - return 3.0F / (shadowMapSize * 0.5F); + return 3.0F / (shadowMapSize * 0.5F); default: break; } @@ -1554,40 +1480,10 @@ SubpassBuilder *addRenderSubpassImpl( const LayoutGraphData &layoutGraph, LayoutGraphData::vertex_descriptor passLayoutID, const ccstd::string &subpassName, uint32_t count, uint32_t quality) { // NOLINT(bugprone-easily-swappable-parameters) - CC_EXPECTS(!subpassName.empty()); auto &pass = get(RasterPassTag{}, passID, renderGraph); - auto &subpassGraph = pass.subpassGraph; - const auto subpassIndex = num_vertices(pass.subpassGraph); - { - auto id = addVertex( - std::piecewise_construct, - std::forward_as_tuple(subpassName), - std::forward_as_tuple(), - subpassGraph); - CC_ENSURES(id == subpassIndex); - } - - RasterSubpass subpass(subpassIndex, count, quality, renderGraph.get_allocator()); - subpass.viewport.width = pass.width; - subpass.viewport.height = pass.height; - - auto subpassID = addVertex( - RasterSubpassTag{}, - std::forward_as_tuple(subpassName), - std::forward_as_tuple(subpassName), - std::forward_as_tuple(), - std::forward_as_tuple(), - std::forward_as_tuple(std::move(subpass)), - renderGraph, passID); - - auto subpassLayoutID = LayoutGraphData::null_vertex(); - if constexpr (ENABLE_SUBPASS) { - subpassLayoutID = locate(passLayoutID, subpassName, layoutGraph); - } else { - subpassLayoutID = locate(LayoutGraphData::null_vertex(), subpassName, layoutGraph); - } - CC_EXPECTS(subpassLayoutID != LayoutGraphData::null_vertex()); + auto [subpassID, subpassLayoutID] = addRenderSubpassVertex( + pass, renderGraph, passID, layoutGraph, passLayoutID, subpassName, count, quality); auto *builder = ccnew SubpassBuilder( pipelineRuntime, &renderGraph, subpassID, &layoutGraph, subpassLayoutID); @@ -1658,6 +1554,135 @@ void NativeRenderPassBuilder::setVersion(const ccstd::string &name, uint64_t ver // noop } +void NativeBasicMultisampleRenderPassBuilder::addRenderTarget( + const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) { + addRasterViewImpl( + name, + "", + "", + AccessType::WRITE, + AttachmentType::RENDER_TARGET, + loadOp, + storeOp, + gfx::ClearFlagBit::COLOR, + color, + subpassID, + *renderGraph); +} + +void NativeBasicMultisampleRenderPassBuilder::addDepthStencil( + const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, + float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) { // NOLINT(bugprone-easily-swappable-parameters) + addRasterViewImpl( + name, + "", + "", + AccessType::WRITE, + AttachmentType::DEPTH_STENCIL, + loadOp, + storeOp, + clearFlags, + gfx::Color{depth, static_cast(stencil)}, + subpassID, + *renderGraph); +} + +void NativeBasicMultisampleRenderPassBuilder::addTexture( + const ccstd::string &name, const ccstd::string &slotName, // NOLINT(bugprone-easily-swappable-parameters) + gfx::Sampler *sampler, uint32_t plane) { + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + subpassID, + name, + ComputeView{ + ccstd::pmr::string(slotName, renderGraph->get_allocator()), + AccessType::READ, + plane, + gfx::ClearFlagBit::NONE, + ClearValueType::NONE, + ClearValue{}, + gfx::ShaderStageFlagBit::NONE, + renderGraph->get_allocator()}); + if (sampler) { + auto iter = layoutGraph->attributeIndex.find(std::string_view{slotName}); + if (iter != layoutGraph->attributeIndex.end()) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, subpassID); + data.samplers[iter->second.value] = sampler; + } + } +} + +RenderQueueBuilder *NativeBasicMultisampleRenderPassBuilder::addQueue( + QueueHint hint, const ccstd::string &phaseName) { + CC_EXPECTS(!phaseName.empty()); + CC_EXPECTS(subpassLayoutID == layoutID); + CC_EXPECTS(subpassLayoutID != LayoutGraphData::null_vertex()); + + const auto phaseLayoutID = locate(subpassLayoutID, phaseName, *layoutGraph); + CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); + + auto queueID = addVertex( + QueueTag{}, + std::forward_as_tuple(phaseName), + std::forward_as_tuple(phaseName), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(hint, phaseLayoutID), + *renderGraph, subpassID); + + return new NativeRenderQueueBuilder(pipelineRuntime, renderGraph, queueID, layoutGraph, phaseLayoutID); +} + +void NativeBasicMultisampleRenderPassBuilder::setViewport(const gfx::Viewport &viewport) { + auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + subpass.viewport = viewport; +} + +void NativeBasicMultisampleRenderPassBuilder::setVersion(const ccstd::string &name, uint64_t version) { + // noop +} + +bool NativeBasicMultisampleRenderPassBuilder::getShowStatistics() const { + const auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + return subpass.showStatistics; +} + +void NativeBasicMultisampleRenderPassBuilder::setShowStatistics(bool enable) { + auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + subpass.showStatistics = enable; +} + +void NativeBasicMultisampleRenderPassBuilder::resolveRenderTarget( + const ccstd::string &source, const ccstd::string &target) { // NOLINT(bugprone-easily-swappable-parameters) + auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + subpass.resolvePairs.emplace_back( + ccstd::pmr::string(source.data(), renderGraph->get_allocator()), + ccstd::pmr::string(target.data(), renderGraph->get_allocator()), + ResolveFlags::COLOR, + gfx::ResolveMode::AVERAGE, + gfx::ResolveMode::NONE); +} + +void NativeBasicMultisampleRenderPassBuilder::resolveDepthStencil( + const ccstd::string &source, const ccstd::string &target, // NOLINT(bugprone-easily-swappable-parameters) + gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) { // NOLINT(bugprone-easily-swappable-parameters) + auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + ResolveFlags flags = ResolveFlags::NONE; + if (depthMode != gfx::ResolveMode::NONE) { + flags |= ResolveFlags::DEPTH; + } + if (stencilMode != gfx::ResolveMode::NONE) { + flags |= ResolveFlags::STENCIL; + } + subpass.resolvePairs.emplace_back( + ccstd::pmr::string(source.data(), renderGraph->get_allocator()), + ccstd::pmr::string(target.data(), renderGraph->get_allocator()), + flags, + depthMode, + stencilMode); +} + // NativeComputeQueue void NativeComputeQueueBuilder::addDispatch( uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ, @@ -1682,8 +1707,10 @@ void NativeComputeQueueBuilder::addDispatch( void NativeComputePassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) { - addComputeView( - *this, + addPassComputeViewImpl( + ComputeTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1705,8 +1732,10 @@ void NativeComputePassBuilder::addTexture( void NativeComputePassBuilder::addStorageBuffer( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addPassComputeViewImpl( + ComputeTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), @@ -1720,8 +1749,10 @@ void NativeComputePassBuilder::addStorageBuffer( void NativeComputePassBuilder::addStorageImage( const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { - addComputeView( - *this, + addPassComputeViewImpl( + ComputeTag{}, + *renderGraph, + nodeID, name, ComputeView{ ccstd::pmr::string(slotName, renderGraph->get_allocator()), diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h new file mode 100644 index 00000000000..6b43d7ac71d --- /dev/null +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h @@ -0,0 +1,164 @@ +#pragma once +#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/NativeTypes.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" +#include "pipeline/custom/RenderGraphTypes.h" + +namespace cc { + +namespace render { + +inline std::tuple +addRenderPassVertex( + RenderGraph &renderGraph, const LayoutGraphData &layoutGraph, + uint32_t width, uint32_t height, // NOLINT(bugprone-easily-swappable-parameters) + uint32_t count, uint32_t quality, // NOLINT(bugprone-easily-swappable-parameters) + const ccstd::string &passName) { + RasterPass pass(renderGraph.get_allocator()); + pass.width = width; + pass.height = height; + pass.viewport.width = width; + pass.viewport.height = height; + pass.count = count; + pass.quality = quality; + + auto passID = addVertex( + RasterPassTag{}, + std::forward_as_tuple(passName), + std::forward_as_tuple(passName), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(pass)), + renderGraph); + + auto passLayoutID = locate(LayoutGraphData::null_vertex(), passName, layoutGraph); + CC_EXPECTS(passLayoutID != LayoutGraphData::null_vertex()); + + return {passID, passLayoutID}; +} + +inline std::tuple +addRenderSubpassVertex( + RasterPass &pass, + RenderGraph &renderGraph, RenderGraph::vertex_descriptor passID, + const LayoutGraphData &layoutGraph, LayoutGraphData::vertex_descriptor passLayoutID, + const ccstd::string &subpassName, + uint32_t count, uint32_t quality) { // NOLINT(bugprone-easily-swappable-parameters) + + // if subpassName is empty, it must be basic multisample render pass + CC_EXPECTS(!subpassName.empty() || count > 1); + + auto &subpassGraph = pass.subpassGraph; + const auto subpassIndex = num_vertices(pass.subpassGraph); + { + auto id = addVertex( + std::piecewise_construct, + std::forward_as_tuple(subpassName), + std::forward_as_tuple(), + subpassGraph); + CC_ENSURES(id == subpassIndex); + } + + RasterSubpass subpass(subpassIndex, count, quality, renderGraph.get_allocator()); + subpass.viewport.width = pass.width; + subpass.viewport.height = pass.height; + + auto subpassID = addVertex( + RasterSubpassTag{}, + std::forward_as_tuple(subpassName), + std::forward_as_tuple(subpassName), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(subpass)), + renderGraph, passID); + + auto subpassLayoutID = LayoutGraphData::null_vertex(); + if (subpassName.empty()) { // Basic multisample render pass (single subpass) + CC_EXPECTS(count > 1); + subpassLayoutID = passLayoutID; + } else { + if constexpr (ENABLE_SUBPASS) { + subpassLayoutID = locate(passLayoutID, subpassName, layoutGraph); + } else { + subpassLayoutID = locate(LayoutGraphData::null_vertex(), subpassName, layoutGraph); + } + } + CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex()); + + return {subpassID, subpassLayoutID}; +} + +template +void addPassComputeViewImpl( + Tag tag, + RenderGraph &renderGraph, + RenderGraph::vertex_descriptor passID, + const ccstd::string &name, const ComputeView &view) { + std::ignore = tag; + CC_EXPECTS(!name.empty()); + CC_EXPECTS(!view.name.empty()); + auto &pass = get(Tag{}, passID, renderGraph); + auto iter = pass.computeViews.find(name.c_str()); + if (iter == pass.computeViews.end()) { + bool added = false; + std::tie(iter, added) = pass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); +} + +template +void addSubpassComputeViewImpl( + Tag tag, + RenderGraph &renderGraph, + RenderGraph::vertex_descriptor subpassID, + const ccstd::string &name, const ComputeView &view) { + std::ignore = tag; + CC_EXPECTS(!name.empty()); + CC_EXPECTS(!view.name.empty()); + auto &subpass = get(Tag{}, subpassID, renderGraph); + const auto passID = parent(subpassID, renderGraph); + CC_EXPECTS(passID != RenderGraph::null_vertex()); + CC_EXPECTS(holds(passID, renderGraph)); + auto &pass = get(RasterPassTag{}, passID, renderGraph); + CC_EXPECTS(subpass.subpassID < num_vertices(pass.subpassGraph)); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + CC_EXPECTS(subpass.computeViews.size() == subpassData.computeViews.size()); + { + auto iter = subpassData.computeViews.find(name.c_str()); + if (iter == subpassData.computeViews.end()) { + bool added = false; + std::tie(iter, added) = subpassData.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); + } + { + auto iter = subpass.computeViews.find(name.c_str()); + if (iter == subpass.computeViews.end()) { + bool added = false; + std::tie(iter, added) = subpass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple()); + CC_ENSURES(added); + } + iter->second.emplace_back(view); + } + CC_ENSURES(subpass.computeViews.size() == subpassData.computeViews.size()); + CC_ENSURES(subpass.computeViews.find(std::string_view{name}) != subpass.computeViews.end()); + CC_ENSURES(subpassData.computeViews.find(std::string_view{name}) != subpassData.computeViews.end()); + CC_ENSURES(subpass.computeViews.find(std::string_view{name})->second.size() == + subpassData.computeViews.find(std::string_view{name})->second.size()); +} + +} // namespace render + +} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h index c88d1732b0d..e57bd08c57d 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h @@ -49,6 +49,7 @@ class RenderNode; class Setter; class RenderQueueBuilder; class BasicRenderPassBuilder; +class BasicMultisampleRenderPassBuilder; class BasicPipeline; class RenderSubpassBuilder; class MultisampleRenderSubpassBuilder; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 3a2d25b3a39..e55a9baaa63 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -290,6 +290,11 @@ enum class SubpassCapabilities : uint32_t { * @zh 支持读取当前像素任意颜色值 */ INPUT_COLOR_MRT = 1 << 2, + /** + * @en Each subpass has its own sample count. + * @zh 每个Subpass拥有不同的采样数 + */ + HETEROGENEOUS_SAMPLE_COUNT = 1 << 3, }; constexpr SubpassCapabilities operator|(const SubpassCapabilities lhs, const SubpassCapabilities rhs) noexcept { @@ -636,6 +641,20 @@ class BasicRenderPassBuilder : public Setter { } }; +class BasicMultisampleRenderPassBuilder : public BasicRenderPassBuilder { +public: + BasicMultisampleRenderPassBuilder() noexcept = default; + + virtual void resolveRenderTarget(const ccstd::string &source, const ccstd::string &target) = 0; + virtual void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target, gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) = 0; + void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target) { + resolveDepthStencil(source, target, gfx::ResolveMode::SAMPLE_ZERO, gfx::ResolveMode::SAMPLE_ZERO); + } + void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target, gfx::ResolveMode depthMode) { + resolveDepthStencil(source, target, depthMode, gfx::ResolveMode::SAMPLE_ZERO); + } +}; + /** * @en BasicPipeline * Basic pipeline provides basic rendering features which are supported on all platforms. @@ -770,7 +789,7 @@ class BasicPipeline : public PipelineRuntime { * @param passName @en Pass name declared in the effect. Default value is 'default' @zh effect中的pass name,缺省为'default' * @returns Multisample basic render pass builder */ - virtual BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) = 0; + virtual BasicMultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) = 0; /** * @deprecated Method will be removed in 3.9.0 */ @@ -815,7 +834,7 @@ class BasicPipeline : public PipelineRuntime { BasicRenderPassBuilder *addRenderPass(uint32_t width, uint32_t height) { return addRenderPass(width, height, "default"); } - BasicRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality) { + BasicMultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality) { return addMultisampleRenderPass(width, height, count, quality, "default"); } }; From 704bfb75549156c76a6a284df993f204c386886b Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Thu, 29 Jun 2023 19:09:32 +0800 Subject: [PATCH 35/57] add MultisampleRenderPassBuilder --- cocos/rendering/custom/pipeline.ts | 17 ++++++ .../pipeline/custom/NativePipeline.cpp | 4 +- .../pipeline/custom/NativePipelineFwd.h | 2 +- .../pipeline/custom/NativePipelineTypes.h | 9 ++-- .../pipeline/custom/NativeRenderGraph.cpp | 54 +++++++++++++++---- .../pipeline/custom/RenderInterfaceFwd.h | 1 + .../pipeline/custom/RenderInterfaceTypes.h | 9 ++++ 7 files changed, 80 insertions(+), 16 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 688724a4c0b..c1d7875c6b0 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -1068,6 +1068,17 @@ export interface RenderPassBuilder extends BasicRenderPassBuilder { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } +export interface MultisampleRenderPassBuilder extends BasicMultisampleRenderPassBuilder { + addStorageBuffer ( + name: string, + accessType: AccessType, + slotName: string): void; + addStorageImage ( + name: string, + accessType: AccessType, + slotName: string): void; +} + /** * @en Compute pass * @zh 计算通道 @@ -1273,6 +1284,12 @@ export interface Pipeline extends BasicPipeline { width: number, height: number, passName: string): RenderPassBuilder; + addMultisampleRenderPass ( + width: number, + height: number, + count: number, + quality: number, + passName: string): MultisampleRenderPassBuilder; /** * @en Add compute pass * @zh 添加计算通道 diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index a6cae32f6df..c7ce4fcb43e 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -538,7 +538,7 @@ RenderPassBuilder *NativePipeline::addRenderPass( return builder; } -BasicMultisampleRenderPassBuilder *NativePipeline::addMultisampleRenderPass( +MultisampleRenderPassBuilder *NativePipeline::addMultisampleRenderPass( uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) { @@ -557,7 +557,7 @@ BasicMultisampleRenderPassBuilder *NativePipeline::addMultisampleRenderPass( "", // subpassName is empty count, quality); - auto *builder = ccnew NativeBasicMultisampleRenderPassBuilder( + auto *builder = ccnew NativeMultisampleRenderPassBuilder( this, &renderGraph, passID, &layoutGraph, passLayoutID, subpassID, subpassLayoutID); diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h index c4a04781c12..71387358734 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h @@ -46,7 +46,7 @@ class NativeRenderSubpassBuilder; class NativeMultisampleRenderSubpassBuilder; class NativeComputeSubpassBuilder; class NativeRenderPassBuilder; -class NativeBasicMultisampleRenderPassBuilder; +class NativeMultisampleRenderPassBuilder; class NativeComputeQueueBuilder; class NativeComputePassBuilder; class NativeSceneTransversal; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index 70d6435b83c..bd515c4709b 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -475,9 +475,9 @@ class NativeRenderPassBuilder final : public RenderPassBuilder, public NativeSet void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) override; }; -class NativeBasicMultisampleRenderPassBuilder final : public BasicMultisampleRenderPassBuilder, public NativeSetter { +class NativeMultisampleRenderPassBuilder final : public MultisampleRenderPassBuilder, public NativeSetter { public: - NativeBasicMultisampleRenderPassBuilder(const PipelineRuntime* pipelineRuntimeIn, RenderGraph* renderGraphIn, uint32_t nodeIDIn, const LayoutGraphData* layoutGraphIn, uint32_t layoutIDIn, uint32_t subpassIDIn, uint32_t subpassLayoutIDIn) noexcept // NOLINT + NativeMultisampleRenderPassBuilder(const PipelineRuntime* pipelineRuntimeIn, RenderGraph* renderGraphIn, uint32_t nodeIDIn, const LayoutGraphData* layoutGraphIn, uint32_t layoutIDIn, uint32_t subpassIDIn, uint32_t subpassLayoutIDIn) noexcept // NOLINT : NativeSetter(pipelineRuntimeIn, renderGraphIn, nodeIDIn, layoutGraphIn, layoutIDIn), subpassID(subpassIDIn), subpassLayoutID(subpassLayoutIDIn) {} @@ -541,6 +541,9 @@ class NativeBasicMultisampleRenderPassBuilder final : public BasicMultisampleRen void resolveRenderTarget(const ccstd::string &source, const ccstd::string &target) override; void resolveDepthStencil(const ccstd::string &source, const ccstd::string &target, gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) override; + void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; + void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; + uint32_t subpassID{RenderGraph::null_vertex()}; uint32_t subpassLayoutID{RenderGraph::null_vertex()}; }; @@ -1179,7 +1182,6 @@ class NativePipeline final : public Pipeline { void beginFrame() override; void update(const scene::Camera *camera) override; void endFrame() override; - BasicMultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) override; void addResolvePass(const ccstd::vector &resolvePairs) override; void addCopyPass(const ccstd::vector ©Pairs) override; gfx::DescriptorSetLayout *getDescriptorSetLayout(const ccstd::string &shaderName, UpdateFrequency freq) override; @@ -1191,6 +1193,7 @@ class NativePipeline final : public Pipeline { void updateStorageTexture(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) override; void updateShadingRateTexture(const ccstd::string &name, uint32_t width, uint32_t height) override; RenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) override; + MultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) override; ComputePassBuilder *addComputePass(const ccstd::string &passName) override; void addUploadPass(ccstd::vector &uploadPairs) override; void addMovePass(const ccstd::vector &movePairs) override; diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 4f318d74a96..a606d827990 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -1554,7 +1554,7 @@ void NativeRenderPassBuilder::setVersion(const ccstd::string &name, uint64_t ver // noop } -void NativeBasicMultisampleRenderPassBuilder::addRenderTarget( +void NativeMultisampleRenderPassBuilder::addRenderTarget( const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) { addRasterViewImpl( name, @@ -1570,7 +1570,7 @@ void NativeBasicMultisampleRenderPassBuilder::addRenderTarget( *renderGraph); } -void NativeBasicMultisampleRenderPassBuilder::addDepthStencil( +void NativeMultisampleRenderPassBuilder::addDepthStencil( const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) { // NOLINT(bugprone-easily-swappable-parameters) addRasterViewImpl( @@ -1587,7 +1587,7 @@ void NativeBasicMultisampleRenderPassBuilder::addDepthStencil( *renderGraph); } -void NativeBasicMultisampleRenderPassBuilder::addTexture( +void NativeMultisampleRenderPassBuilder::addTexture( const ccstd::string &name, const ccstd::string &slotName, // NOLINT(bugprone-easily-swappable-parameters) gfx::Sampler *sampler, uint32_t plane) { addSubpassComputeViewImpl( @@ -1613,7 +1613,41 @@ void NativeBasicMultisampleRenderPassBuilder::addTexture( } } -RenderQueueBuilder *NativeBasicMultisampleRenderPassBuilder::addQueue( +void NativeMultisampleRenderPassBuilder::addStorageBuffer( + const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + subpassID, + name, + ComputeView{ + ccstd::pmr::string(slotName, renderGraph->get_allocator()), + accessType, + gfx::ClearFlagBit::NONE, + ClearValueType::NONE, + ClearValue{}, + gfx::ShaderStageFlagBit::NONE, + renderGraph->get_allocator()}); +} + +void NativeMultisampleRenderPassBuilder::addStorageImage( + const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) { + addSubpassComputeViewImpl( + RasterSubpassTag{}, + *renderGraph, + subpassID, + name, + ComputeView{ + ccstd::pmr::string(slotName, renderGraph->get_allocator()), + accessType, + gfx::ClearFlagBit::NONE, + ClearValueType::NONE, + ClearValue{}, + gfx::ShaderStageFlagBit::NONE, + renderGraph->get_allocator()}); +} + +RenderQueueBuilder *NativeMultisampleRenderPassBuilder::addQueue( QueueHint hint, const ccstd::string &phaseName) { CC_EXPECTS(!phaseName.empty()); CC_EXPECTS(subpassLayoutID == layoutID); @@ -1634,26 +1668,26 @@ RenderQueueBuilder *NativeBasicMultisampleRenderPassBuilder::addQueue( return new NativeRenderQueueBuilder(pipelineRuntime, renderGraph, queueID, layoutGraph, phaseLayoutID); } -void NativeBasicMultisampleRenderPassBuilder::setViewport(const gfx::Viewport &viewport) { +void NativeMultisampleRenderPassBuilder::setViewport(const gfx::Viewport &viewport) { auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); subpass.viewport = viewport; } -void NativeBasicMultisampleRenderPassBuilder::setVersion(const ccstd::string &name, uint64_t version) { +void NativeMultisampleRenderPassBuilder::setVersion(const ccstd::string &name, uint64_t version) { // noop } -bool NativeBasicMultisampleRenderPassBuilder::getShowStatistics() const { +bool NativeMultisampleRenderPassBuilder::getShowStatistics() const { const auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); return subpass.showStatistics; } -void NativeBasicMultisampleRenderPassBuilder::setShowStatistics(bool enable) { +void NativeMultisampleRenderPassBuilder::setShowStatistics(bool enable) { auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); subpass.showStatistics = enable; } -void NativeBasicMultisampleRenderPassBuilder::resolveRenderTarget( +void NativeMultisampleRenderPassBuilder::resolveRenderTarget( const ccstd::string &source, const ccstd::string &target) { // NOLINT(bugprone-easily-swappable-parameters) auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); subpass.resolvePairs.emplace_back( @@ -1664,7 +1698,7 @@ void NativeBasicMultisampleRenderPassBuilder::resolveRenderTarget( gfx::ResolveMode::NONE); } -void NativeBasicMultisampleRenderPassBuilder::resolveDepthStencil( +void NativeMultisampleRenderPassBuilder::resolveDepthStencil( const ccstd::string &source, const ccstd::string &target, // NOLINT(bugprone-easily-swappable-parameters) gfx::ResolveMode depthMode, gfx::ResolveMode stencilMode) { // NOLINT(bugprone-easily-swappable-parameters) auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h index e57bd08c57d..0bbcf866469 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h @@ -56,6 +56,7 @@ class MultisampleRenderSubpassBuilder; class ComputeQueueBuilder; class ComputeSubpassBuilder; class RenderPassBuilder; +class MultisampleRenderPassBuilder; class ComputePassBuilder; class SceneVisitor; class SceneTask; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index e55a9baaa63..0c40193d4a1 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -1206,6 +1206,14 @@ class RenderPassBuilder : public BasicRenderPassBuilder { } }; +class MultisampleRenderPassBuilder : public BasicMultisampleRenderPassBuilder { +public: + MultisampleRenderPassBuilder() noexcept = default; + + virtual void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; + virtual void addStorageImage(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) = 0; +}; + /** * @en Compute pass * @zh 计算通道 @@ -1408,6 +1416,7 @@ class Pipeline : public BasicPipeline { */ virtual void updateShadingRateTexture(const ccstd::string &name, uint32_t width, uint32_t height) = 0; RenderPassBuilder *addRenderPass(uint32_t width, uint32_t height, const ccstd::string &passName) override = 0 /* covariant */; + MultisampleRenderPassBuilder *addMultisampleRenderPass(uint32_t width, uint32_t height, uint32_t count, uint32_t quality, const ccstd::string &passName) override = 0 /* covariant */; /** * @en Add compute pass * @zh 添加计算通道 From 474828bc458762cef18d73071e09cfbcd7a5bc13 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 30 Jun 2023 16:45:09 +0800 Subject: [PATCH 36/57] refactor interface, adding gpu-driven --- cocos/rendering/custom/pipeline.ts | 16 + cocos/rendering/custom/types.ts | 1 + cocos/rendering/custom/web-pipeline.ts | 52 +- native/CMakeLists.txt | 4 + .../renderer/pipeline/RenderPipeline.cpp | 2 +- .../pipeline/custom/NativeBuiltinUtils.cpp | 533 +++++++++ .../pipeline/custom/NativeBuiltinUtils.h | 62 + .../pipeline/custom/NativePipeline.cpp | 43 +- .../pipeline/custom/NativePipelineTypes.h | 103 ++ .../pipeline/custom/NativeRenderGraph.cpp | 1042 +---------------- .../custom/NativeRenderGraphUtils.cpp | 327 ++++++ .../pipeline/custom/NativeRenderGraphUtils.h | 30 + .../pipeline/custom/NativeSceneCulling.cpp | 15 +- .../renderer/pipeline/custom/NativeSetter.cpp | 129 ++ .../renderer/pipeline/custom/NativeUtils.cpp | 129 +- .../renderer/pipeline/custom/NativeUtils.h | 12 +- .../pipeline/custom/RenderCommonTypes.h | 1 + .../pipeline/custom/RenderInterfaceTypes.h | 10 + 18 files changed, 1322 insertions(+), 1189 deletions(-) create mode 100644 native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp create mode 100644 native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h create mode 100644 native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp create mode 100644 native/cocos/renderer/pipeline/custom/NativeSetter.cpp diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index c1d7875c6b0..b71e1e83be6 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -30,6 +30,7 @@ /* eslint-disable max-len */ import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; +import { DirectionalLight } from '../../render-scene/scene/directional-light'; import { GeometryRenderer } from '../geometry-renderer'; import { Buffer, BufferInfo, ClearFlagBit, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, LoadOp, PipelineState, Rect, ResolveMode, Sampler, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureInfo, Viewport } from '../../gfx'; import { GlobalDSManager } from '../global-descriptor-set-manager'; @@ -39,6 +40,7 @@ import { PipelineSceneData } from '../pipeline-scene-data'; import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; +import { SpotLight } from '../../render-scene/scene/spot-light'; /** * @engineInternal @@ -373,6 +375,10 @@ export interface Setter extends RenderNode { * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 */ setSampler (name: string, sampler: Sampler): void; + setBuiltinCameraConstants (camera: Camera): void; + setBuiltinShadowMapConstants (light: DirectionalLight): void; + setBuiltinDirectionalLightViewConstants (light: DirectionalLight, level?: number): void; + setBuiltinSpotLightViewConstants (light: SpotLight): void; } /** @@ -396,6 +402,16 @@ export interface RenderQueueBuilder extends Setter { camera: Camera, light: LightInfo, sceneFlags?: SceneFlags): void; + addScene (camera: Camera, sceneFlags: SceneFlags): void; + addSceneCulledByDirectionalLight ( + camera: Camera, + sceneFlags: SceneFlags, + light: DirectionalLight, + level: number): void; + addSceneCulledBySpotLight ( + camera: Camera, + sceneFlags: SceneFlags, + light: SpotLight): void; /** * @en Render a full-screen quad. * @zh 渲染全屏四边形 diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index c964335b4ff..d2ab00e415a 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -205,6 +205,7 @@ export enum SceneFlags { DRAW_INSTANCING = 0x800, DRAW_NON_INSTANCING = 0x1000, REFLECTION_PROBE = 0x2000, + GPU_DRIVEN = 0x4000, ALL = 0xFFFFFFFF, } diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index d1209fcdb22..1a30d49f8f4 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -249,18 +249,18 @@ export class WebSetter { const num = this._lg.attributeIndex.get(name)!; this._data.samplers.set(num, sampler); } - // public setCameraConstants (camera: Camera): void { + public setBuiltinCameraConstants (camera: Camera): void { - // } - // public setDirectionalLightProjectionConstants (light: DirectionalLight): void { + } + public setBuiltinShadowMapConstants (light: Light, numLevels?: number): void { - // } - // public setSpotLightProjectionConstants (light: SpotLight): void { + } + public setBuiltinDirectionalLightViewConstants (light: DirectionalLight): void { - // } - // public setShadowMapConstants (light: Light, numLevels?: number): void { + } + public setBuiltinSpotLightViewConstants (light: SpotLight): void { - // } + } public hasSampler (name: string): boolean { const id = this._lg.attributeIndex.get(name); if (id === undefined) { @@ -828,24 +828,24 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild setTextureUBOView(this, camera, this._pipeline); initGlobalDescBinding(this._data, layoutName); } - // addScene (camera: Camera, sceneFlags = SceneFlags.NONE): void { - // const sceneData = new SceneData(camera.scene, camera, sceneFlags); - // this._renderGraph.addVertex( - // RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - // ); - // } - // addSceneCulledByDirectionalLight (camera: Camera, sceneFlags: SceneFlags, light: DirectionalLight, level: number): void { - // const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, level)); - // this._renderGraph.addVertex( - // RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - // ); - // } - // addSceneCulledBySpotLight (camera: Camera, sceneFlags: SceneFlags, light: SpotLight): void { - // const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, 0)); - // this._renderGraph.addVertex( - // RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - // ); - // } + addScene (camera: Camera, sceneFlags = SceneFlags.NONE): void { + const sceneData = new SceneData(camera.scene, camera, sceneFlags); + this._renderGraph.addVertex( + RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, + ); + } + addSceneCulledByDirectionalLight (camera: Camera, sceneFlags: SceneFlags, light: DirectionalLight, level: number): void { + const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, level)); + this._renderGraph.addVertex( + RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, + ); + } + addSceneCulledBySpotLight (camera: Camera, sceneFlags: SceneFlags, light: SpotLight): void { + const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, 0)); + this._renderGraph.addVertex( + RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, + ); + } addFullscreenQuad (material: Material, passID: number, sceneFlags = SceneFlags.NONE, name = 'Quad'): void { this._renderGraph.addVertex( RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, null), diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 8118c07d256..e1130ee0d66 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -1410,6 +1410,8 @@ cocos_source_files( cocos/renderer/pipeline/custom/LayoutGraphTypes.h cocos/renderer/pipeline/custom/LayoutGraphUtils.cpp cocos/renderer/pipeline/custom/LayoutGraphUtils.h + cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp + cocos/renderer/pipeline/custom/NativeBuiltinUtils.h cocos/renderer/pipeline/custom/NativeDefaultScene.cpp cocos/renderer/pipeline/custom/NativeExecutor.cpp cocos/renderer/pipeline/custom/NativeFactory.cpp @@ -1422,11 +1424,13 @@ cocos_source_files( cocos/renderer/pipeline/custom/NativePools.cpp cocos/renderer/pipeline/custom/NativeProgramLibrary.cpp cocos/renderer/pipeline/custom/NativeRenderGraph.cpp + cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h cocos/renderer/pipeline/custom/NativeRenderQueue.cpp cocos/renderer/pipeline/custom/NativeRenderingModule.cpp cocos/renderer/pipeline/custom/NativeResourceGraph.cpp cocos/renderer/pipeline/custom/NativeSceneCulling.cpp + cocos/renderer/pipeline/custom/NativeSetter.cpp cocos/renderer/pipeline/custom/NativeTypes.cpp cocos/renderer/pipeline/custom/NativeTypes.h cocos/renderer/pipeline/custom/NativeUtils.cpp diff --git a/native/cocos/renderer/pipeline/RenderPipeline.cpp b/native/cocos/renderer/pipeline/RenderPipeline.cpp index 7cbecfdf110..4dc96a47421 100644 --- a/native/cocos/renderer/pipeline/RenderPipeline.cpp +++ b/native/cocos/renderer/pipeline/RenderPipeline.cpp @@ -40,7 +40,7 @@ #if CC_USE_DEBUG_RENDERER #include "profiler/DebugRenderer.h" #endif -#include "custom/NativeUtils.h" +#include "custom/NativeBuiltinUtils.h" #include "scene/Camera.h" #include "scene/Skybox.h" diff --git a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp new file mode 100644 index 00000000000..3172c80d969 --- /dev/null +++ b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp @@ -0,0 +1,533 @@ +#include "NativeBuiltinUtils.h" +#include "cocos/application/ApplicationManager.h" +#include "cocos/renderer/gfx-base/GFXDef-common.h" +#include "cocos/renderer/gfx-base/GFXDevice.h" +#include "cocos/renderer/pipeline/PipelineSceneData.h" +#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h" +#include "cocos/renderer/pipeline/custom/NativeTypes.h" +#include "cocos/renderer/pipeline/custom/NativeUtils.h" +#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" +#include "cocos/scene/Camera.h" +#include "cocos/scene/Fog.h" +#include "cocos/scene/Skybox.h" +#include "cocos/scene/SpotLight.h" + +namespace cc { + +namespace render { + +void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]) { + auto minX = static_cast(viewport.x); + auto maxX = static_cast(viewport.x + viewport.z); + auto minY = static_cast(viewport.y); + auto maxY = static_cast(viewport.y + viewport.w); + if (device.getCapabilities().screenSpaceSignY > 0) { + std::swap(minY, maxY); + } + int n = 0; + vbData[n++] = -1.0F; + vbData[n++] = -1.0F; + vbData[n++] = minX; // uv + vbData[n++] = maxY; + vbData[n++] = 1.0F; + vbData[n++] = -1.0F; + vbData[n++] = maxX; + vbData[n++] = maxY; + vbData[n++] = -1.0F; + vbData[n++] = 1.0F; + vbData[n++] = minX; + vbData[n++] = minY; + vbData[n++] = 1.0F; + vbData[n++] = 1.0F; + vbData[n++] = maxX; + vbData[n++] = minY; +} + +// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) +void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter) { + const auto &root = *Root::getInstance(); + const auto shadingWidth = static_cast(width); + const auto shadingHeight = static_cast(height); + setter.setVec4( + "cc_time", + Vec4( + root.getCumulativeTime(), + root.getFrameTime(), + static_cast(CC_CURRENT_ENGINE()->getTotalFrames()), + 0.0F)); + + setter.setVec4( + "cc_screenSize", + Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight)); + setter.setVec4( + "cc_nativeSize", + Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight)); +#if 0 + const auto *debugView = root.getDebugView(); + if (debugView) { + setter.setVec4( + "cc_debug_view_mode", + Vec4(static_cast(debugView->getSingleMode()), + debugView->isLightingWithAlbedo() ? 1.0F : 0.0F, + debugView->isCsmLayerColoration() ? 1.0F : 0.0F, + 0.0F)); + Vec4 debugPackVec{}; + for (auto i = static_cast(pipeline::DebugViewCompositeType::DIRECT_DIFFUSE); + i < static_cast(pipeline::DebugViewCompositeType::MAX_BIT_COUNT); ++i) { + const auto idx = i % 4; + (&debugPackVec.x)[idx] = debugView->isCompositeModeEnabled(i) ? 1.0F : 0.0F; + const auto packIdx = static_cast(floor(static_cast(i) / 4.0F)); + if (idx == 3) { + std::string name("cc_debug_view_composite_pack_"); + name.append(std::to_string(packIdx + 1)); + setter.setVec4(name, debugPackVec); + } + } + } else { + setter.setVec4("cc_debug_view_mode", Vec4(0.0F, 1.0F, 0.0F, 0.0F)); + Vec4 debugPackVec{}; + for (auto i = static_cast(pipeline::DebugViewCompositeType::DIRECT_DIFFUSE); + i < static_cast(pipeline::DebugViewCompositeType::MAX_BIT_COUNT); ++i) { + const auto idx = i % 4; + (&debugPackVec.x)[idx] = 1.0F; + const auto packIdx = static_cast(floor(i / 4.0)); + if (idx == 3) { + std::string name("cc_debug_view_composite_pack_"); + name.append(std::to_string(packIdx + 1)); + setter.setVec4(name, debugPackVec); + } + } + } +#endif +} + +namespace { + +uint8_t getCombineSignY(gfx::Device *device) { + // 0: vk, 1: metal, 2: none, 3: gl-like + static int8_t combineSignY{-1}; + if (combineSignY < 0) { + const float screenSpaceSignY = device->getCapabilities().screenSpaceSignY * 0.5F + 0.5F; + const float clipSpaceSignY = device->getCapabilities().clipSpaceSignY * 0.5F + 0.5F; + combineSignY = static_cast(static_cast(screenSpaceSignY) << 1 | static_cast(clipSpaceSignY)); + } + return static_cast(combineSignY); +} + +} // namespace + +void setCameraUBOValues( + const scene::Camera &camera, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &cfg, + const scene::DirectionalLight *mainLight, + RenderData &data) { + CC_EXPECTS(camera.getNode()); + CC_EXPECTS(cfg.getSkybox()); + const auto &skybox = *cfg.getSkybox(); + const auto &shadingScale = cfg.getShadingScale(); + // Camera + setMat4Impl(data, layoutGraph, "cc_matView", camera.getMatView()); + setMat4Impl(data, layoutGraph, "cc_matViewInv", camera.getNode()->getWorldMatrix()); + setMat4Impl(data, layoutGraph, "cc_matProj", camera.getMatProj()); + setMat4Impl(data, layoutGraph, "cc_matProjInv", camera.getMatProjInv()); + setMat4Impl(data, layoutGraph, "cc_matViewProj", camera.getMatViewProj()); + setMat4Impl(data, layoutGraph, "cc_matViewProjInv", camera.getMatViewProjInv()); + setVec4Impl(data, layoutGraph, "cc_cameraPos", + Vec4( + camera.getPosition().x, + camera.getPosition().y, + camera.getPosition().z, + getCombineSignY(cc::gfx::Device::getInstance()))); + setVec4Impl(data, layoutGraph, "cc_surfaceTransform", + Vec4( + static_cast(camera.getSurfaceTransform()), + static_cast(camera.getCameraUsage()), + cosf(static_cast(mathutils::toRadian(skybox.getRotationAngle()))), + sinf(static_cast(mathutils::toRadian(skybox.getRotationAngle()))))); + setVec4Impl(data, layoutGraph, "cc_screenScale", + Vec4( + cfg.getShadingScale(), + cfg.getShadingScale(), + 1.0F / cfg.getShadingScale(), + 1.0F / cfg.getShadingScale())); + setVec4Impl(data, layoutGraph, "cc_exposure", + Vec4( + camera.getExposure(), + 1.0F / camera.getExposure(), + cfg.isHDR() ? 1.0F : 0.0F, + 1.0F / scene::Camera::getStandardExposureValue())); + + if (mainLight) { + const auto &shadowInfo = *cfg.getShadows(); + const bool shadowEnable = (mainLight->isShadowEnabled() && + shadowInfo.getType() == scene::ShadowType::SHADOW_MAP); + setVec4Impl(data, layoutGraph, "cc_mainLitDir", + Vec4( + mainLight->getDirection().x, + mainLight->getDirection().y, + mainLight->getDirection().z, + shadowEnable)); + auto r = mainLight->getColor().x; + auto g = mainLight->getColor().y; + auto b = mainLight->getColor().z; + if (mainLight->isUseColorTemperature()) { + r *= mainLight->getColorTemperatureRGB().x; + g *= mainLight->getColorTemperatureRGB().y; + b *= mainLight->getColorTemperatureRGB().z; + } + auto w = mainLight->getIlluminance(); + if (cfg.isHDR()) { + w *= camera.getExposure(); + } + setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(r, g, b, w)); + } else { + setVec4Impl(data, layoutGraph, "cc_mainLitDir", Vec4(0, 0, 1, 0)); + setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(0, 0, 0, 0)); + } + + CC_EXPECTS(cfg.getAmbient()); + auto &ambient = *cfg.getAmbient(); + auto &skyColor = ambient.getSkyColor(); + if (cfg.isHDR()) { + skyColor.w = ambient.getSkyIllum() * camera.getExposure(); + } else { + skyColor.w = ambient.getSkyIllum(); + } + setVec4Impl(data, layoutGraph, "cc_ambientSky", + Vec4(skyColor.x, skyColor.y, skyColor.z, skyColor.w)); + setVec4Impl(data, layoutGraph, "cc_ambientGround", + Vec4( + ambient.getGroundAlbedo().x, + ambient.getGroundAlbedo().y, + ambient.getGroundAlbedo().z, + skybox.getEnvmap() ? static_cast(skybox.getEnvmap()->mipmapLevel()) : 1.0F)); + + CC_EXPECTS(cfg.getFog()); + const auto &fog = *cfg.getFog(); + + const auto &colorTempRGB = fog.getColorArray(); + setVec4Impl(data, layoutGraph, "cc_fogColor", + Vec4(colorTempRGB.x, colorTempRGB.y, colorTempRGB.z, colorTempRGB.z)); + setVec4Impl(data, layoutGraph, "cc_fogBase", + Vec4(fog.getFogStart(), fog.getFogEnd(), fog.getFogDensity(), 0.0F)); + setVec4Impl(data, layoutGraph, "cc_fogAdd", + Vec4(fog.getFogTop(), fog.getFogRange(), fog.getFogAtten(), 0.0F)); + setVec4Impl(data, layoutGraph, "cc_nearFar", + Vec4(camera.getNearClip(), camera.getFarClip(), camera.getClipSpaceMinz(), 0.0F)); + setVec4Impl(data, layoutGraph, "cc_viewPort", + Vec4( + camera.getViewport().x, + camera.getViewport().y, + shadingScale * static_cast(camera.getWindow()->getWidth()) * camera.getViewport().z, + shadingScale * static_cast(camera.getWindow()->getHeight()) * camera.getViewport().w)); +} + +namespace { + +float getPCFRadius( + const scene::Shadows &shadowInfo, + const scene::DirectionalLight &mainLight) { + const auto &shadowMapSize = shadowInfo.getSize().x; + switch (mainLight.getShadowPcf()) { + case scene::PCFType::HARD: + return 0.0F; + case scene::PCFType::SOFT: + return 1.0F / (shadowMapSize * 0.5F); + case scene::PCFType::SOFT_2X: + return 2.0F / (shadowMapSize * 0.5F); + case scene::PCFType::SOFT_4X: + return 3.0F / (shadowMapSize * 0.5F); + default: + break; + } + return 0.0F; +} + +} // namespace + +void setShadowUBOView( + gfx::Device &device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + const scene::DirectionalLight &mainLight, + RenderData &data) { + const auto &shadowInfo = *sceneData.getShadows(); + const auto &csmLayers = *sceneData.getCSMLayers(); + const auto &csmSupported = sceneData.getCSMSupported(); + const auto &packing = pipeline::supportsR32FloatTexture(&device) ? 0.0F : 1.0F; + Vec4 vec4ShadowInfo{}; + if (shadowInfo.isEnabled()) { + if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) { + if (mainLight.isShadowEnabled()) { + if (mainLight.isShadowFixedArea() || + mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1 || !csmSupported) { + // Shadow + const auto &matShadowView = csmLayers.getSpecialLayer()->getMatShadowView(); + const auto &matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj(); + const auto &matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj(); + const auto &near = mainLight.getShadowNear(); + const auto &far = mainLight.getShadowFar(); + + setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); + setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo", + Vec4(matShadowProj.m[10], matShadowProj.m[14], + matShadowProj.m[11], matShadowProj.m[15])); + + setVec4Impl(data, layoutGraph, "cc_shadowProjInfo", + Vec4(matShadowProj.m[00], matShadowProj.m[05], + 1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05])); + setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); + vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation()); + setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); + vec4ShadowInfo.set(static_cast(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0); + setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); + } else { + { // CSM + const auto layerThreshold = getPCFRadius(shadowInfo, mainLight); + const auto numCascades = static_cast(mainLight.getCSMLevel()); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir0", numCascades); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir1", numCascades); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir2", numCascades); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmAtlas", numCascades); + setMat4ArraySizeImpl(data, layoutGraph, "cc_matCSMViewProj", numCascades); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjDepthInfo", numCascades); + setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjInfo", numCascades); + + Vec4 csmSplitsInfo{}; + for (uint32_t i = 0; i < numCascades; ++i) { + const auto &layer = *csmLayers.getLayers()[i]; + + const auto &matShadowView = layer.getMatShadowView(); + vec4ShadowInfo.set(matShadowView.m[0], matShadowView.m[4], matShadowView.m[8], layerThreshold); + setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir0", vec4ShadowInfo, i); + vec4ShadowInfo.set(matShadowView.m[1], matShadowView.m[5], matShadowView.m[9], layer.getSplitCameraNear()); + setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir1", vec4ShadowInfo, i); + vec4ShadowInfo.set(matShadowView.m[2], matShadowView.m[6], matShadowView.m[10], layer.getSplitCameraFar()); + setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir2", vec4ShadowInfo, i); + + const auto &csmAtlas = layer.getCSMAtlas(); + setVec4ArrayElemImpl(data, layoutGraph, "cc_csmAtlas", csmAtlas, i); + + const auto &matShadowViewProj = layer.getMatShadowViewProj(); + setMat4ArrayElemImpl(data, layoutGraph, "cc_matCSMViewProj", matShadowViewProj, i); + + const auto &matShadowProj = layer.getMatShadowProj(); + setVec4ArrayElemImpl(data, layoutGraph, + "cc_csmProjDepthInfo", + Vec4(matShadowProj.m[10], matShadowProj.m[14], + matShadowProj.m[11], matShadowProj.m[15]), + i); + + setVec4ArrayElemImpl(data, layoutGraph, + "cc_csmProjInfo", + Vec4(matShadowProj.m[00], matShadowProj.m[05], + 1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05]), + i); + + (&csmSplitsInfo.x)[i] = layer.getSplitCameraFar() / mainLight.getShadowDistance(); + } + setVec4Impl(data, layoutGraph, "cc_csmSplitsInfo", csmSplitsInfo); + } + { // Shadow + vec4ShadowInfo.set(0, 0, 0, 1.0F - mainLight.getShadowSaturation()); + setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); + vec4ShadowInfo.set( + static_cast(scene::LightType::DIRECTIONAL), + packing, + mainLight.getShadowNormalBias(), + static_cast(mainLight.getCSMLevel())); + setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); + } + } + { // Shadow + vec4ShadowInfo.set( + shadowInfo.getSize().x, shadowInfo.getSize().y, + static_cast(mainLight.getShadowPcf()), mainLight.getShadowBias()); + setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo); + } + } + } else { + Vec3 tempVec3 = shadowInfo.getNormal().getNormalized(); + setVec4Impl(data, layoutGraph, + "cc_planarNDInfo", + Vec4(tempVec3.x, tempVec3.y, tempVec3.z, -shadowInfo.getDistance())); + } + { + const auto &color = shadowInfo.getShadowColor4f(); + setColorImpl(data, layoutGraph, "cc_shadowColor", + gfx::Color{color[0], color[1], color[2], color[3]}); + } + } +} + +void setShadowUBOLightView( + gfx::Device *device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + const scene::Light &light, + uint32_t level, + RenderData &data) { + const auto &shadowInfo = *sceneData.getShadows(); + const auto &csmLayers = *sceneData.getCSMLayers(); + const auto &packing = pipeline::supportsR32FloatTexture(device) ? 0.0F : 1.0F; + const auto &cap = device->getCapabilities(); + Vec4 vec4ShadowInfo{}; + + // ShadowMap + switch (light.getType()) { + case scene::LightType::DIRECTIONAL: { + const auto &mainLight = dynamic_cast(light); + if (shadowInfo.isEnabled() && mainLight.isShadowEnabled()) { + if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) { + float near = 0.1F; + float far = 0.0F; + Mat4 matShadowView; + Mat4 matShadowProj; + Mat4 matShadowViewProj; + scene::CSMLevel levelCount{}; + if (mainLight.isShadowFixedArea() || mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1) { + matShadowView = csmLayers.getSpecialLayer()->getMatShadowView(); + matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj(); + matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj(); + if (mainLight.isShadowFixedArea()) { + near = mainLight.getShadowNear(); + far = mainLight.getShadowFar(); + levelCount = static_cast(0); + } else { + near = 0.1F; + far = csmLayers.getSpecialLayer()->getShadowCameraFar(); + levelCount = scene::CSMLevel::LEVEL_1; + } + vec4ShadowInfo.set(static_cast(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0); + setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); + } else { + const auto &layer = *csmLayers.getLayers()[level]; + matShadowView = layer.getMatShadowView(); + matShadowProj = layer.getMatShadowProj(); + matShadowViewProj = layer.getMatShadowViewProj(); + + near = layer.getSplitCameraNear(); + far = layer.getSplitCameraFar(); + levelCount = mainLight.getCSMLevel(); + } + setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); + setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo", + Vec4( + matShadowProj.m[10], + matShadowProj.m[14], + matShadowProj.m[11], + matShadowProj.m[15])); + setVec4Impl(data, layoutGraph, "cc_shadowProjInfo", + Vec4( + matShadowProj.m[00], + matShadowProj.m[05], + 1.0F / matShadowProj.m[00], + 1.0F / matShadowProj.m[05])); + setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); + vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation()); + setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); + vec4ShadowInfo.set( + static_cast(scene::LightType::DIRECTIONAL), + packing, + mainLight.getShadowNormalBias(), + static_cast(levelCount)); + setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); + vec4ShadowInfo.set( + shadowInfo.getSize().x, + shadowInfo.getSize().y, + static_cast(mainLight.getShadowPcf()), + mainLight.getShadowBias()); + setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo); + } + } + break; + } + case scene::LightType::SPOT: { + const auto &spotLight = dynamic_cast(light); + if (shadowInfo.isEnabled() && spotLight.isShadowEnabled()) { + const auto &matShadowCamera = spotLight.getNode()->getWorldMatrix(); + const auto matShadowView = matShadowCamera.getInversed(); + setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); + + Mat4 matShadowViewProj{}; + Mat4::createPerspective(spotLight.getAngle(), 1.0F, 0.001F, + spotLight.getRange(), true, + cap.clipSpaceMinZ, cap.clipSpaceSignY, 0, &matShadowViewProj); + matShadowViewProj.multiply(matShadowView); + setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); + + const Vec4 shadowNFLSInfos(0.01F, spotLight.getRange(), 0.0F, 0.0F); + setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", shadowNFLSInfos); + + const Vec4 shadowWHPBInfos( + shadowInfo.getSize().x, + shadowInfo.getSize().y, + spotLight.getShadowPcf(), + spotLight.getShadowBias()); + setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", shadowWHPBInfos); + + const Vec4 shadowLPNNInfos(static_cast(scene::LightType::SPOT), packing, spotLight.getShadowNormalBias(), 0.0F); + setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", shadowLPNNInfos); + } + break; + } + default: + break; + } + + const auto &color = shadowInfo.getShadowColor4f(); + setColorImpl(data, layoutGraph, "cc_shadowColor", gfx::Color{color[0], color[1], color[2], color[3]}); +} + +void setLegacyTextureUBOView( + gfx::Device &device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + RenderData &data) { + const auto &skybox = *sceneData.getSkybox(); + if (skybox.getReflectionMap()) { + auto &texture = *skybox.getReflectionMap()->getGFXTexture(); + auto *sampler = device.getSampler(skybox.getReflectionMap()->getSamplerInfo()); + setTextureImpl(data, layoutGraph, "cc_environment", &texture); + setSamplerImpl(data, layoutGraph, "cc_environment", sampler); + } else { + const auto *envmap = + skybox.getEnvmap() + ? skybox.getEnvmap() + : BuiltinResMgr::getInstance()->get("default-cube-texture"); + if (envmap) { + auto *texture = envmap->getGFXTexture(); + auto *sampler = device.getSampler(envmap->getSamplerInfo()); + setTextureImpl(data, layoutGraph, "cc_environment", texture); + setSamplerImpl(data, layoutGraph, "cc_environment", sampler); + } + } + const auto *diffuseMap = + skybox.getDiffuseMap() + ? skybox.getDiffuseMap() + : BuiltinResMgr::getInstance()->get("default-cube-texture"); + if (diffuseMap) { + auto *texture = diffuseMap->getGFXTexture(); + auto *sampler = device.getSampler(diffuseMap->getSamplerInfo()); + setTextureImpl(data, layoutGraph, "cc_diffuseMap", texture); + setSamplerImpl(data, layoutGraph, "cc_diffuseMap", sampler); + } + gfx::SamplerInfo samplerPointInfo{ + gfx::Filter::POINT, + gfx::Filter::POINT, + gfx::Filter::NONE, + gfx::Address::CLAMP, + gfx::Address::CLAMP, + gfx::Address::CLAMP}; + auto *pointSampler = device.getSampler(samplerPointInfo); + setSamplerImpl(data, layoutGraph, "cc_shadowMap", pointSampler); + // setTextureImpl(data, layoutGraph, "cc_shadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); + setSamplerImpl(data, layoutGraph, "cc_spotShadowMap", pointSampler); + // setTextureImpl(data, layoutGraph, "cc_spotShadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); +} + +} // namespace render + +} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h new file mode 100644 index 00000000000..8e74ba1a4f3 --- /dev/null +++ b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h" +#include "cocos/renderer/pipeline/custom/NativeFwd.h" +#include "cocos/renderer/pipeline/custom/RenderGraphFwd.h" + +namespace cc { + +namespace scene { +class Camera; +class DirectionalLight; +} // namespace scene + +namespace gfx { +class Device; +} // namespace gfx + +namespace pipeline { +class PipelineSceneData; +} // namespace pipeline + +namespace render { + +void setCameraUBOValues( + const scene::Camera &camera, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &cfg, + const scene::DirectionalLight *mainLight, + RenderData &data); + +void setLegacyTextureUBOView( + gfx::Device &device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + RenderData &data); + +// For use shadow map +void setShadowUBOView( + gfx::Device &device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + const scene::DirectionalLight &mainLight, + RenderData &data); + +// For build shadow map +void setShadowUBOLightView( + gfx::Device *device, + const LayoutGraphData &layoutGraph, + const pipeline::PipelineSceneData &sceneData, + const scene::Light &light, + uint32_t level, + RenderData &data); + +// Render graph +void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter); + +// Geometry +void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]); + +} // namespace render + +} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index c7ce4fcb43e..5614fa51793 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -22,45 +22,18 @@ THE SOFTWARE. ****************************************************************************/ -#include -#include -#include "LayoutGraphFwd.h" -#include "LayoutGraphGraphs.h" -#include "LayoutGraphNames.h" -#include "LayoutGraphTypes.h" -#include "LayoutGraphUtils.h" -#include "NativePipelineFwd.h" -#include "NativePipelineTypes.h" -#include "NativeRenderGraphUtils.h" -#include "NativeUtils.h" -#include "RenderCommonTypes.h" -#include "RenderGraphGraphs.h" -#include "RenderGraphTypes.h" -#include "RenderInterfaceFwd.h" -#include "RenderInterfaceTypes.h" -#include "RenderingModule.h" -#include "cocos/base/Macros.h" -#include "cocos/base/Ptr.h" -#include "cocos/base/StringUtil.h" -#include "cocos/base/std/container/string.h" -#include "cocos/math/Mat4.h" -#include "cocos/renderer/gfx-base/GFXBuffer.h" -#include "cocos/renderer/gfx-base/GFXDef-common.h" -#include "cocos/renderer/gfx-base/GFXDescriptorSetLayout.h" -#include "cocos/renderer/gfx-base/GFXDevice.h" -#include "cocos/renderer/gfx-base/GFXInputAssembler.h" -#include "cocos/renderer/gfx-base/GFXSwapchain.h" -#include "cocos/renderer/gfx-base/states/GFXSampler.h" -#include "cocos/renderer/pipeline/Enum.h" -#include "cocos/renderer/pipeline/GlobalDescriptorSetManager.h" #include "cocos/renderer/pipeline/PipelineSceneData.h" #include "cocos/renderer/pipeline/PipelineStateManager.h" -#include "cocos/renderer/pipeline/RenderPipeline.h" +#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h" +#include "cocos/renderer/pipeline/custom/LayoutGraphUtils.h" +#include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h" +#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" +#include "cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/RenderingModule.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" #include "cocos/scene/RenderScene.h" #include "cocos/scene/RenderWindow.h" -#include "details/DebugUtils.h" -#include "details/GslUtils.h" - #if CC_USE_DEBUG_RENDERER #include "profiler/DebugRenderer.h" #endif diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index bd515c4709b..d4686c0ccd4 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -86,6 +86,10 @@ class NativeSetter : public NativeRenderNode { void setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) /*implements*/; void setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) /*implements*/; void setSampler(const ccstd::string &name, gfx::Sampler *sampler) /*implements*/; + void setBuiltinCameraConstants(const scene::Camera *camera) /*implements*/; + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) /*implements*/; + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) /*implements*/; + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) /*implements*/; void setVec4ArraySize(const ccstd::string& name, uint32_t sz); void setVec4ArrayElem(const ccstd::string& name, const cc::Vec4& vec, uint32_t id); @@ -165,8 +169,23 @@ class NativeRenderQueueBuilder final : public RenderQueueBuilder, public NativeS void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addSceneOfCamera(scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) override; + void addScene(const scene::Camera *camera, SceneFlags sceneFlags) override; + void addSceneCulledByDirectionalLight(const scene::Camera *camera, SceneFlags sceneFlags, scene::DirectionalLight *light, uint32_t level) override; + void addSceneCulledBySpotLight(const scene::Camera *camera, SceneFlags sceneFlags, scene::SpotLight *light) override; void addFullscreenQuad(Material *material, uint32_t passID, SceneFlags sceneFlags) override; void addCameraQuad(scene::Camera *camera, Material *material, uint32_t passID, SceneFlags sceneFlags) override; void clearRenderTarget(const ccstd::string &name, const gfx::Color &color) override; @@ -225,6 +244,18 @@ class NativeRenderSubpassBuilder final : public RenderSubpassBuilder, public Nat void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addRenderTarget(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override { NativeRenderSubpassBuilderImpl::addRenderTarget(name, accessType, slotName, loadOp, storeOp, color); @@ -309,6 +340,18 @@ class NativeMultisampleRenderSubpassBuilder final : public MultisampleRenderSubp void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addRenderTarget(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override { NativeRenderSubpassBuilderImpl::addRenderTarget(name, accessType, slotName, loadOp, storeOp, color); @@ -396,6 +439,18 @@ class NativeComputeSubpassBuilder final : public ComputeSubpassBuilder, public N void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addRenderTarget(const ccstd::string &name, const ccstd::string &slotName) override; void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) override; @@ -456,6 +511,18 @@ class NativeRenderPassBuilder final : public RenderPassBuilder, public NativeSet void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override; void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) override; @@ -528,6 +595,18 @@ class NativeMultisampleRenderPassBuilder final : public MultisampleRenderPassBui void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addRenderTarget(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, const gfx::Color &color) override; void addDepthStencil(const ccstd::string &name, gfx::LoadOp loadOp, gfx::StoreOp storeOp, float depth, uint8_t stencil, gfx::ClearFlagBit clearFlags) override; @@ -599,6 +678,18 @@ class NativeComputeQueueBuilder final : public ComputeQueueBuilder, public Nativ void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addDispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ, Material *material, uint32_t passID) override; }; @@ -654,6 +745,18 @@ class NativeComputePassBuilder final : public ComputePassBuilder, public NativeS void setSampler(const ccstd::string &name, gfx::Sampler *sampler) override { NativeSetter::setSampler(name, sampler); } + void setBuiltinCameraConstants(const scene::Camera *camera) override { + NativeSetter::setBuiltinCameraConstants(camera); + } + void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) override { + NativeSetter::setBuiltinShadowMapConstants(light); + } + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) override { + NativeSetter::setBuiltinDirectionalLightViewConstants(light, level); + } + void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) override { + NativeSetter::setBuiltinSpotLightViewConstants(light); + } void addTexture(const ccstd::string &name, const ccstd::string &slotName, gfx::Sampler *sampler, uint32_t plane) override; void addStorageBuffer(const ccstd::string &name, AccessType accessType, const ccstd::string &slotName) override; diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index a606d827990..28b9be1176b 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -22,32 +22,14 @@ THE SOFTWARE. ****************************************************************************/ -#include -#include -#include "LayoutGraphGraphs.h" -#include "NativePipelineGraphs.h" -#include "NativePipelineTypes.h" -#include "NativeRenderGraphUtils.h" -#include "NativeUtils.h" -#include "RenderCommonNames.h" -#include "RenderCommonTypes.h" -#include "RenderGraphFwd.h" -#include "RenderGraphGraphs.h" -#include "RenderGraphTypes.h" -#include "RenderingModule.h" -#include "cocos/math/Utils.h" -#include "cocos/renderer/pipeline/Define.h" -#include "cocos/renderer/pipeline/PipelineUBO.h" +#include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h" +#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" +#include "cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h" +#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" #include "cocos/scene/DirectionalLight.h" -#include "cocos/scene/Fog.h" -#include "cocos/scene/Skybox.h" +#include "cocos/scene/RenderScene.h" #include "cocos/scene/SpotLight.h" -#include "details/DebugUtils.h" -#include "details/GraphView.h" -#include "details/GslUtils.h" -#include "gfx-base/GFXDef-common.h" -#include "gfx-base/GFXDevice.h" -#include "pipeline/PipelineSceneData.h" namespace cc { @@ -65,300 +47,6 @@ void NativeRenderNode::setCustomBehavior(const ccstd::string &name) { // NOLINT( get(RenderGraph::DataTag{}, *renderGraph, nodeID).custom = std::string_view{name}; } -void NativeSetter::setMat4(const ccstd::string &name, const Mat4 &mat) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setMat4Impl(data, *layoutGraph, name, mat); -} - -void NativeSetter::setQuaternion(const ccstd::string &name, const Quaternion &quat) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setQuaternionImpl(data, *layoutGraph, name, quat); -} - -void NativeSetter::setColor(const ccstd::string &name, const gfx::Color &color) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setColorImpl(data, *layoutGraph, name, color); -} - -void NativeSetter::setVec4(const ccstd::string &name, const Vec4 &vec) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setVec4Impl(data, *layoutGraph, name, vec); -} - -void NativeSetter::setVec2(const ccstd::string &name, const Vec2 &vec) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setVec2Impl(data, *layoutGraph, name, vec); -} - -void NativeSetter::setFloat(const ccstd::string &name, float v) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setFloatImpl(data, *layoutGraph, name, v); -} - -void NativeSetter::setArrayBuffer(const ccstd::string &name, const ArrayBuffer *buffer) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setArrayBufferImpl(data, *layoutGraph, name, *buffer); -} - -void NativeSetter::setBuffer(const ccstd::string &name, gfx::Buffer *buffer) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setBufferImpl(data, *layoutGraph, name, buffer); -} - -void NativeSetter::setTexture(const ccstd::string &name, gfx::Texture *texture) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setTextureImpl(data, *layoutGraph, name, texture); -} - -void NativeSetter::setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setReadWriteBufferImpl(data, *layoutGraph, name, buffer); -} - -void NativeSetter::setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setReadWriteTextureImpl(data, *layoutGraph, name, texture); -} - -void NativeSetter::setSampler(const ccstd::string &name, gfx::Sampler *sampler) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setSamplerImpl(data, *layoutGraph, name, sampler); -} - -void NativeSetter::setVec4ArraySize(const ccstd::string &name, uint32_t sz) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setVec4ArraySizeImpl(data, *layoutGraph, name, sz); -} - -void NativeSetter::setVec4ArrayElem(const ccstd::string &name, const cc::Vec4 &vec, uint32_t id) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setVec4ArrayElemImpl(data, *layoutGraph, name, vec, id); -} - -void NativeSetter::setMat4ArraySize(const ccstd::string &name, uint32_t sz) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setMat4ArraySizeImpl(data, *layoutGraph, name, sz); -} - -void NativeSetter::setMat4ArrayElem(const ccstd::string &name, const cc::Mat4 &mat, uint32_t id) { - auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - setMat4ArrayElemImpl(data, *layoutGraph, name, mat, id); -} - -namespace { - -uint8_t getCombineSignY(gfx::Device *device) { - // 0: vk, 1: metal, 2: none, 3: gl-like - static int8_t combineSignY{-1}; - if (combineSignY < 0) { - const float screenSpaceSignY = device->getCapabilities().screenSpaceSignY * 0.5F + 0.5F; - const float clipSpaceSignY = device->getCapabilities().clipSpaceSignY * 0.5F + 0.5F; - combineSignY = static_cast(static_cast(screenSpaceSignY) << 1 | static_cast(clipSpaceSignY)); - } - return static_cast(combineSignY); -} - -void setCameraUBOValues( - const scene::Camera &camera, - const LayoutGraphData &layoutGraph, - const pipeline::PipelineSceneData &cfg, - const scene::DirectionalLight *mainLight, - RenderData &data) { - CC_EXPECTS(camera.getNode()); - CC_EXPECTS(cfg.getSkybox()); - const auto &skybox = *cfg.getSkybox(); - const auto &shadingScale = cfg.getShadingScale(); - // Camera - setMat4Impl(data, layoutGraph, "cc_matView", camera.getMatView()); - setMat4Impl(data, layoutGraph, "cc_matViewInv", camera.getNode()->getWorldMatrix()); - setMat4Impl(data, layoutGraph, "cc_matProj", camera.getMatProj()); - setMat4Impl(data, layoutGraph, "cc_matProjInv", camera.getMatProjInv()); - setMat4Impl(data, layoutGraph, "cc_matViewProj", camera.getMatViewProj()); - setMat4Impl(data, layoutGraph, "cc_matViewProjInv", camera.getMatViewProjInv()); - setVec4Impl(data, layoutGraph, "cc_cameraPos", - Vec4( - camera.getPosition().x, - camera.getPosition().y, - camera.getPosition().z, - getCombineSignY(cc::gfx::Device::getInstance()))); - setVec4Impl(data, layoutGraph, "cc_surfaceTransform", - Vec4( - static_cast(camera.getSurfaceTransform()), - static_cast(camera.getCameraUsage()), - cosf(static_cast(mathutils::toRadian(skybox.getRotationAngle()))), - sinf(static_cast(mathutils::toRadian(skybox.getRotationAngle()))))); - setVec4Impl(data, layoutGraph, "cc_screenScale", - Vec4( - cfg.getShadingScale(), - cfg.getShadingScale(), - 1.0F / cfg.getShadingScale(), - 1.0F / cfg.getShadingScale())); - setVec4Impl(data, layoutGraph, "cc_exposure", - Vec4( - camera.getExposure(), - 1.0F / camera.getExposure(), - cfg.isHDR() ? 1.0F : 0.0F, - 1.0F / scene::Camera::getStandardExposureValue())); - - if (mainLight) { - const auto &shadowInfo = *cfg.getShadows(); - const bool shadowEnable = (mainLight->isShadowEnabled() && - shadowInfo.getType() == scene::ShadowType::SHADOW_MAP); - setVec4Impl(data, layoutGraph, "cc_mainLitDir", - Vec4( - mainLight->getDirection().x, - mainLight->getDirection().y, - mainLight->getDirection().z, - shadowEnable)); - auto r = mainLight->getColor().x; - auto g = mainLight->getColor().y; - auto b = mainLight->getColor().z; - if (mainLight->isUseColorTemperature()) { - r *= mainLight->getColorTemperatureRGB().x; - g *= mainLight->getColorTemperatureRGB().y; - b *= mainLight->getColorTemperatureRGB().z; - } - auto w = mainLight->getIlluminance(); - if (cfg.isHDR()) { - w *= camera.getExposure(); - } - setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(r, g, b, w)); - } else { - setVec4Impl(data, layoutGraph, "cc_mainLitDir", Vec4(0, 0, 1, 0)); - setVec4Impl(data, layoutGraph, "cc_mainLitColor", Vec4(0, 0, 0, 0)); - } - - CC_EXPECTS(cfg.getAmbient()); - auto &ambient = *cfg.getAmbient(); - auto &skyColor = ambient.getSkyColor(); - if (cfg.isHDR()) { - skyColor.w = ambient.getSkyIllum() * camera.getExposure(); - } else { - skyColor.w = ambient.getSkyIllum(); - } - setVec4Impl(data, layoutGraph, "cc_ambientSky", - Vec4(skyColor.x, skyColor.y, skyColor.z, skyColor.w)); - setVec4Impl(data, layoutGraph, "cc_ambientGround", - Vec4( - ambient.getGroundAlbedo().x, - ambient.getGroundAlbedo().y, - ambient.getGroundAlbedo().z, - skybox.getEnvmap() ? static_cast(skybox.getEnvmap()->mipmapLevel()) : 1.0F)); - - CC_EXPECTS(cfg.getFog()); - const auto &fog = *cfg.getFog(); - - const auto &colorTempRGB = fog.getColorArray(); - setVec4Impl(data, layoutGraph, "cc_fogColor", - Vec4(colorTempRGB.x, colorTempRGB.y, colorTempRGB.z, colorTempRGB.z)); - setVec4Impl(data, layoutGraph, "cc_fogBase", - Vec4(fog.getFogStart(), fog.getFogEnd(), fog.getFogDensity(), 0.0F)); - setVec4Impl(data, layoutGraph, "cc_fogAdd", - Vec4(fog.getFogTop(), fog.getFogRange(), fog.getFogAtten(), 0.0F)); - setVec4Impl(data, layoutGraph, "cc_nearFar", - Vec4(camera.getNearClip(), camera.getFarClip(), camera.getClipSpaceMinz(), 0.0F)); - setVec4Impl(data, layoutGraph, "cc_viewPort", - Vec4( - camera.getViewport().x, - camera.getViewport().y, - shadingScale * static_cast(camera.getWindow()->getWidth()) * camera.getViewport().z, - shadingScale * static_cast(camera.getWindow()->getHeight()) * camera.getViewport().w)); -} - -} // namespace - -// void NativeSetter::setCameraConstants(const scene::Camera *camera) { -// auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); -// setCameraUBOValues( -// *camera, -// *layoutGraph, -// *pipelineRuntime->getPipelineSceneData(), -// camera->getScene()->getMainLight(), data); -// } - -// void NativeSetter::setDirectionalLightProjectionConstants( -// const scene::DirectionalLight* light, uint32_t level) { -// CC_EXPECTS(light); -// const auto *device = pipelineRuntime->getDevice(); -// const auto &mainLight = *light; -// const auto& pplScenData = *pipelineRuntime->getPipelineSceneData(); -// const auto &shadowInfo = *pplScenData.getShadows(); -// const auto &csmLayers = *pplScenData.getCSMLayers(); -// const auto packing = pipeline::supportsR32FloatTexture(device) ? 0.0F : 1.0F; - -// auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); - -// float near = 0.1; -// float far = 0; -// Mat4 matShadowView; -// Mat4 matShadowProj; -// Mat4 matShadowViewProj; -// Vec4 vec4ShadowInfo{}; - -// scene::CSMLevel levelCount{}; -// if (mainLight.isShadowFixedArea() || mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1) { -// matShadowView = csmLayers.getSpecialLayer()->getMatShadowView(); -// matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj(); -// matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj(); -// if (mainLight.isShadowFixedArea()) { -// near = mainLight.getShadowNear(); -// far = mainLight.getShadowFar(); -// levelCount = static_cast(0); -// } else { -// near = 0.1; -// far = csmLayers.getSpecialLayer()->getShadowCameraFar(); -// levelCount = scene::CSMLevel::LEVEL_1; -// } -// vec4ShadowInfo.set(0.0F, packing, mainLight.getShadowNormalBias(), 0); -// setVec4Impl(data, *layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); -// } else { -// const auto &layer = *csmLayers.getLayers()[level]; -// matShadowView = layer.getMatShadowView(); -// matShadowProj = layer.getMatShadowProj(); -// matShadowViewProj = layer.getMatShadowViewProj(); - -// near = layer.getSplitCameraNear(); -// far = layer.getSplitCameraFar(); -// levelCount = mainLight.getCSMLevel(); -// } -// setMat4Impl(data, *layoutGraph, "cc_matLightView", matShadowView); -// setVec4Impl(data, *layoutGraph, "cc_shadowProjDepthInfo", -// Vec4( -// matShadowProj.m[10], -// matShadowProj.m[14], -// matShadowProj.m[11], -// matShadowProj.m[15])); -// setVec4Impl(data, *layoutGraph, "cc_shadowProjInfo", -// Vec4( -// matShadowProj.m[00], -// matShadowProj.m[05], -// 1.0F / matShadowProj.m[00], -// 1.0F / matShadowProj.m[05])); -// setMat4Impl(data, *layoutGraph, "cc_matLightViewProj", matShadowViewProj); -// vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation()); -// setVec4Impl(data, *layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); -// vec4ShadowInfo.set( -// 0.0F, -// packing, -// mainLight.getShadowNormalBias(), -// static_cast(levelCount)); -// setVec4Impl(data, *layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); -// vec4ShadowInfo.set( -// shadowInfo.getSize().x, -// shadowInfo.getSize().y, -// static_cast(mainLight.getShadowPcf()), -// mainLight.getShadowBias()); -// setVec4Impl(data, *layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo); -// } - -// void NativeSetter::setSpotLightProjectionConstants(const scene::SpotLight* light) { - -// } - -// void NativeSetter::setShadowMapConstants(const scene::Light* light, uint32_t numLevels) { - -// } - namespace { template @@ -959,310 +647,6 @@ ComputeQueueBuilder *NativeComputeSubpassBuilder::addQueue(const ccstd::string & return new NativeComputeQueueBuilder(pipelineRuntime, renderGraph, queueID, layoutGraph, phaseLayoutID); } -namespace { - -void setShadowUBOLightView( - gfx::Device *device, - const LayoutGraphData &layoutGraph, - const pipeline::PipelineSceneData &sceneData, - const scene::Light &light, - uint32_t level, - RenderData &data) { - const auto &shadowInfo = *sceneData.getShadows(); - const auto &csmLayers = *sceneData.getCSMLayers(); - const auto &packing = pipeline::supportsR32FloatTexture(device) ? 0.0F : 1.0F; - const auto &cap = device->getCapabilities(); - Vec4 vec4ShadowInfo{}; - - // ShadowMap - switch (light.getType()) { - case scene::LightType::DIRECTIONAL: { - const auto &mainLight = dynamic_cast(light); - if (shadowInfo.isEnabled() && mainLight.isShadowEnabled()) { - if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) { - float near = 0.1F; - float far = 0.0F; - Mat4 matShadowView; - Mat4 matShadowProj; - Mat4 matShadowViewProj; - scene::CSMLevel levelCount{}; - if (mainLight.isShadowFixedArea() || mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1) { - matShadowView = csmLayers.getSpecialLayer()->getMatShadowView(); - matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj(); - matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj(); - if (mainLight.isShadowFixedArea()) { - near = mainLight.getShadowNear(); - far = mainLight.getShadowFar(); - levelCount = static_cast(0); - } else { - near = 0.1F; - far = csmLayers.getSpecialLayer()->getShadowCameraFar(); - levelCount = scene::CSMLevel::LEVEL_1; - } - vec4ShadowInfo.set(static_cast(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0); - setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); - } else { - const auto &layer = *csmLayers.getLayers()[level]; - matShadowView = layer.getMatShadowView(); - matShadowProj = layer.getMatShadowProj(); - matShadowViewProj = layer.getMatShadowViewProj(); - - near = layer.getSplitCameraNear(); - far = layer.getSplitCameraFar(); - levelCount = mainLight.getCSMLevel(); - } - setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); - setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo", - Vec4( - matShadowProj.m[10], - matShadowProj.m[14], - matShadowProj.m[11], - matShadowProj.m[15])); - setVec4Impl(data, layoutGraph, "cc_shadowProjInfo", - Vec4( - matShadowProj.m[00], - matShadowProj.m[05], - 1.0F / matShadowProj.m[00], - 1.0F / matShadowProj.m[05])); - setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); - vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation()); - setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); - vec4ShadowInfo.set( - static_cast(scene::LightType::DIRECTIONAL), - packing, - mainLight.getShadowNormalBias(), - static_cast(levelCount)); - setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); - vec4ShadowInfo.set( - shadowInfo.getSize().x, - shadowInfo.getSize().y, - static_cast(mainLight.getShadowPcf()), - mainLight.getShadowBias()); - setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo); - } - } - break; - } - case scene::LightType::SPOT: { - const auto &spotLight = dynamic_cast(light); - if (shadowInfo.isEnabled() && spotLight.isShadowEnabled()) { - const auto &matShadowCamera = spotLight.getNode()->getWorldMatrix(); - const auto matShadowView = matShadowCamera.getInversed(); - setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); - - Mat4 matShadowViewProj{}; - Mat4::createPerspective(spotLight.getAngle(), 1.0F, 0.001F, - spotLight.getRange(), true, - cap.clipSpaceMinZ, cap.clipSpaceSignY, 0, &matShadowViewProj); - matShadowViewProj.multiply(matShadowView); - setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); - - const Vec4 shadowNFLSInfos(0.01F, spotLight.getRange(), 0.0F, 0.0F); - setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", shadowNFLSInfos); - - const Vec4 shadowWHPBInfos( - shadowInfo.getSize().x, - shadowInfo.getSize().y, - spotLight.getShadowPcf(), - spotLight.getShadowBias()); - setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", shadowWHPBInfos); - - const Vec4 shadowLPNNInfos(static_cast(scene::LightType::SPOT), packing, spotLight.getShadowNormalBias(), 0.0F); - setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", shadowLPNNInfos); - } - break; - } - default: - break; - } - - const auto &color = shadowInfo.getShadowColor4f(); - setColorImpl(data, layoutGraph, "cc_shadowColor", gfx::Color{color[0], color[1], color[2], color[3]}); -} - -float getPCFRadius( - const scene::Shadows &shadowInfo, - const scene::DirectionalLight &mainLight) { - const auto &shadowMapSize = shadowInfo.getSize().x; - switch (mainLight.getShadowPcf()) { - case scene::PCFType::HARD: - return 0.0F; - case scene::PCFType::SOFT: - return 1.0F / (shadowMapSize * 0.5F); - case scene::PCFType::SOFT_2X: - return 2.0F / (shadowMapSize * 0.5F); - case scene::PCFType::SOFT_4X: - return 3.0F / (shadowMapSize * 0.5F); - default: - break; - } - return 0.0F; -} - -void setShadowUBOView( - gfx::Device &device, - const LayoutGraphData &layoutGraph, - const pipeline::PipelineSceneData &sceneData, - const scene::DirectionalLight &mainLight, - RenderData &data) { - const auto &shadowInfo = *sceneData.getShadows(); - const auto &csmLayers = *sceneData.getCSMLayers(); - const auto &csmSupported = sceneData.getCSMSupported(); - const auto &packing = pipeline::supportsR32FloatTexture(&device) ? 0.0F : 1.0F; - Vec4 vec4ShadowInfo{}; - if (shadowInfo.isEnabled()) { - if (shadowInfo.getType() == scene::ShadowType::SHADOW_MAP) { - if (mainLight.isShadowEnabled()) { - if (mainLight.isShadowFixedArea() || - mainLight.getCSMLevel() == scene::CSMLevel::LEVEL_1 || !csmSupported) { - // Shadow - const auto &matShadowView = csmLayers.getSpecialLayer()->getMatShadowView(); - const auto &matShadowProj = csmLayers.getSpecialLayer()->getMatShadowProj(); - const auto &matShadowViewProj = csmLayers.getSpecialLayer()->getMatShadowViewProj(); - const auto &near = mainLight.getShadowNear(); - const auto &far = mainLight.getShadowFar(); - - setMat4Impl(data, layoutGraph, "cc_matLightView", matShadowView); - setVec4Impl(data, layoutGraph, "cc_shadowProjDepthInfo", - Vec4(matShadowProj.m[10], matShadowProj.m[14], - matShadowProj.m[11], matShadowProj.m[15])); - - setVec4Impl(data, layoutGraph, "cc_shadowProjInfo", - Vec4(matShadowProj.m[00], matShadowProj.m[05], - 1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05])); - setMat4Impl(data, layoutGraph, "cc_matLightViewProj", matShadowViewProj); - vec4ShadowInfo.set(near, far, 0, 1.0F - mainLight.getShadowSaturation()); - setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); - vec4ShadowInfo.set(static_cast(scene::LightType::DIRECTIONAL), packing, mainLight.getShadowNormalBias(), 0); - setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); - } else { - { // CSM - const auto layerThreshold = getPCFRadius(shadowInfo, mainLight); - const auto numCascades = static_cast(mainLight.getCSMLevel()); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir0", numCascades); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir1", numCascades); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmViewDir2", numCascades); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmAtlas", numCascades); - setMat4ArraySizeImpl(data, layoutGraph, "cc_matCSMViewProj", numCascades); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjDepthInfo", numCascades); - setVec4ArraySizeImpl(data, layoutGraph, "cc_csmProjInfo", numCascades); - - Vec4 csmSplitsInfo{}; - for (uint32_t i = 0; i < numCascades; ++i) { - const auto &layer = *csmLayers.getLayers()[i]; - - const auto &matShadowView = layer.getMatShadowView(); - vec4ShadowInfo.set(matShadowView.m[0], matShadowView.m[4], matShadowView.m[8], layerThreshold); - setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir0", vec4ShadowInfo, i); - vec4ShadowInfo.set(matShadowView.m[1], matShadowView.m[5], matShadowView.m[9], layer.getSplitCameraNear()); - setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir1", vec4ShadowInfo, i); - vec4ShadowInfo.set(matShadowView.m[2], matShadowView.m[6], matShadowView.m[10], layer.getSplitCameraFar()); - setVec4ArrayElemImpl(data, layoutGraph, "cc_csmViewDir2", vec4ShadowInfo, i); - - const auto &csmAtlas = layer.getCSMAtlas(); - setVec4ArrayElemImpl(data, layoutGraph, "cc_csmAtlas", csmAtlas, i); - - const auto &matShadowViewProj = layer.getMatShadowViewProj(); - setMat4ArrayElemImpl(data, layoutGraph, "cc_matCSMViewProj", matShadowViewProj, i); - - const auto &matShadowProj = layer.getMatShadowProj(); - setVec4ArrayElemImpl(data, layoutGraph, - "cc_csmProjDepthInfo", - Vec4(matShadowProj.m[10], matShadowProj.m[14], - matShadowProj.m[11], matShadowProj.m[15]), - i); - - setVec4ArrayElemImpl(data, layoutGraph, - "cc_csmProjInfo", - Vec4(matShadowProj.m[00], matShadowProj.m[05], - 1.0F / matShadowProj.m[00], 1.0F / matShadowProj.m[05]), - i); - - (&csmSplitsInfo.x)[i] = layer.getSplitCameraFar() / mainLight.getShadowDistance(); - } - setVec4Impl(data, layoutGraph, "cc_csmSplitsInfo", csmSplitsInfo); - } - { // Shadow - vec4ShadowInfo.set(0, 0, 0, 1.0F - mainLight.getShadowSaturation()); - setVec4Impl(data, layoutGraph, "cc_shadowNFLSInfo", vec4ShadowInfo); - vec4ShadowInfo.set( - static_cast(scene::LightType::DIRECTIONAL), - packing, - mainLight.getShadowNormalBias(), - static_cast(mainLight.getCSMLevel())); - setVec4Impl(data, layoutGraph, "cc_shadowLPNNInfo", vec4ShadowInfo); - } - } - { // Shadow - vec4ShadowInfo.set( - shadowInfo.getSize().x, shadowInfo.getSize().y, - static_cast(mainLight.getShadowPcf()), mainLight.getShadowBias()); - setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo); - } - } - } else { - Vec3 tempVec3 = shadowInfo.getNormal().getNormalized(); - setVec4Impl(data, layoutGraph, - "cc_planarNDInfo", - Vec4(tempVec3.x, tempVec3.y, tempVec3.z, -shadowInfo.getDistance())); - } - { - const auto &color = shadowInfo.getShadowColor4f(); - setColorImpl(data, layoutGraph, "cc_shadowColor", - gfx::Color{color[0], color[1], color[2], color[3]}); - } - } -} - -void setTextureUBOView( - gfx::Device &device, - const LayoutGraphData &layoutGraph, - const pipeline::PipelineSceneData &sceneData, - RenderData &data) { - const auto &skybox = *sceneData.getSkybox(); - if (skybox.getReflectionMap()) { - auto &texture = *skybox.getReflectionMap()->getGFXTexture(); - auto *sampler = device.getSampler(skybox.getReflectionMap()->getSamplerInfo()); - setTextureImpl(data, layoutGraph, "cc_environment", &texture); - setSamplerImpl(data, layoutGraph, "cc_environment", sampler); - } else { - const auto *envmap = - skybox.getEnvmap() - ? skybox.getEnvmap() - : BuiltinResMgr::getInstance()->get("default-cube-texture"); - if (envmap) { - auto *texture = envmap->getGFXTexture(); - auto *sampler = device.getSampler(envmap->getSamplerInfo()); - setTextureImpl(data, layoutGraph, "cc_environment", texture); - setSamplerImpl(data, layoutGraph, "cc_environment", sampler); - } - } - const auto *diffuseMap = - skybox.getDiffuseMap() - ? skybox.getDiffuseMap() - : BuiltinResMgr::getInstance()->get("default-cube-texture"); - if (diffuseMap) { - auto *texture = diffuseMap->getGFXTexture(); - auto *sampler = device.getSampler(diffuseMap->getSamplerInfo()); - setTextureImpl(data, layoutGraph, "cc_diffuseMap", texture); - setSamplerImpl(data, layoutGraph, "cc_diffuseMap", sampler); - } - gfx::SamplerInfo samplerPointInfo{ - gfx::Filter::POINT, - gfx::Filter::POINT, - gfx::Filter::NONE, - gfx::Address::CLAMP, - gfx::Address::CLAMP, - gfx::Address::CLAMP}; - auto *pointSampler = device.getSampler(samplerPointInfo); - setSamplerImpl(data, layoutGraph, "cc_shadowMap", pointSampler); - // setTextureImpl(data, layoutGraph, "cc_shadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); - setSamplerImpl(data, layoutGraph, "cc_spotShadowMap", pointSampler); - // setTextureImpl(data, layoutGraph, "cc_spotShadowMap", BuiltinResMgr::getInstance()->get("default-texture")->getGFXTexture()); -} - -} // namespace - void NativeRenderQueueBuilder::addSceneOfCamera( scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) { const auto *pLight = light.light.get(); @@ -1302,62 +686,62 @@ void NativeRenderQueueBuilder::addSceneOfCamera( *pDirLight, data); } } - setTextureUBOView( + setLegacyTextureUBOView( *pipelineRuntime->getDevice(), *layoutGraph, *pipelineRuntime->getPipelineSceneData(), data); } -// void NativeRenderQueueBuilder::addScene(const scene::Camera *camera, SceneFlags sceneFlags) { -// SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{}); - -// auto sceneID = addVertex( -// SceneTag{}, -// std::forward_as_tuple("Scene"), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(std::move(data)), -// *renderGraph, nodeID); -// CC_ENSURES(sceneID != RenderGraph::null_vertex()); -// } - -// void NativeRenderQueueBuilder::addSceneCulledByDirectionalLight( -// const scene::Camera *camera, SceneFlags sceneFlags, -// scene::DirectionalLight *light, uint32_t level) { -// CC_EXPECTS(light); -// CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); -// SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, level}); - -// auto sceneID = addVertex( -// SceneTag{}, -// std::forward_as_tuple("Scene"), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(std::move(data)), -// *renderGraph, nodeID); -// CC_ENSURES(sceneID != RenderGraph::null_vertex()); -// } - -// void NativeRenderQueueBuilder::addSceneCulledBySpotLight( -// const scene::Camera *camera, SceneFlags sceneFlags, -// scene::SpotLight *light) { -// CC_EXPECTS(light); -// CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); -// SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, 0}); - -// auto sceneID = addVertex( -// SceneTag{}, -// std::forward_as_tuple("Scene"), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(), -// std::forward_as_tuple(std::move(data)), -// *renderGraph, nodeID); -// CC_ENSURES(sceneID != RenderGraph::null_vertex()); -// } +void NativeRenderQueueBuilder::addScene(const scene::Camera *camera, SceneFlags sceneFlags) { + SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{}); + + auto sceneID = addVertex( + SceneTag{}, + std::forward_as_tuple("Scene"), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(data)), + *renderGraph, nodeID); + CC_ENSURES(sceneID != RenderGraph::null_vertex()); +} + +void NativeRenderQueueBuilder::addSceneCulledByDirectionalLight( + const scene::Camera *camera, SceneFlags sceneFlags, + scene::DirectionalLight *light, uint32_t level) { + CC_EXPECTS(light); + CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); + SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, level}); + + auto sceneID = addVertex( + SceneTag{}, + std::forward_as_tuple("Scene"), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(data)), + *renderGraph, nodeID); + CC_ENSURES(sceneID != RenderGraph::null_vertex()); +} + +void NativeRenderQueueBuilder::addSceneCulledBySpotLight( + const scene::Camera *camera, SceneFlags sceneFlags, + scene::SpotLight *light) { + CC_EXPECTS(light); + CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); + SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, 0}); + + auto sceneID = addVertex( + SceneTag{}, + std::forward_as_tuple("Scene"), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(data)), + *renderGraph, nodeID); + CC_ENSURES(sceneID != RenderGraph::null_vertex()); +} void NativeRenderQueueBuilder::addFullscreenQuad( Material *material, uint32_t passID, SceneFlags sceneFlags) { @@ -1405,7 +789,7 @@ void NativeRenderQueueBuilder::addCameraQuad( *pDirLight, data); } } - setTextureUBOView( + setLegacyTextureUBOView( *pipelineRuntime->getDevice(), *layoutGraph, *pipelineRuntime->getPipelineSceneData(), @@ -1836,318 +1220,6 @@ ComputeQueueBuilder *NativeComputePassBuilder::addQueue(const ccstd::string &pha return new NativeComputeQueueBuilder(pipelineRuntime, renderGraph, queueID, layoutGraph, phaseLayoutID); } -namespace { - -const char *getName(const gfx::LoadOp &op) { - switch (op) { - case gfx::LoadOp::LOAD: - return "LOAD"; - case gfx::LoadOp::CLEAR: - return "CLEAR"; - case gfx::LoadOp::DISCARD: - return "DISCARD"; - default: - return "UNKNOWN"; - } - return "UNKNOWN"; -} - -const char *getName(const gfx::StoreOp &op) { - switch (op) { - case gfx::StoreOp::STORE: - return "STORE"; - case gfx::StoreOp::DISCARD: - return "DISCARD"; - default: - return "UNKNOWN"; - } - return "UNKNOWN"; -} - -std::string getName(const gfx::ClearFlagBit &flags) { - std::ostringstream oss; - int count = 0; - if (hasAnyFlags(flags, gfx::ClearFlagBit::COLOR)) { - if (count++) { - oss << "|"; - } - oss << "COLOR"; - } - if (hasAnyFlags(flags, gfx::ClearFlagBit::DEPTH)) { - if (count++) { - oss << "|"; - } - oss << "DEPTH"; - } - if (hasAnyFlags(flags, gfx::ClearFlagBit::STENCIL)) { - if (count++) { - oss << "|"; - } - oss << "STENCIL"; - } - if (flags == gfx::ClearFlagBit::NONE) { - oss << "NONE"; - } - return oss.str(); -} - -struct RenderGraphPrintVisitor : boost::dfs_visitor<> { - void discover_vertex( - RenderGraph::vertex_descriptor vertID, - const AddressableView &gv) const { - const auto &g = gv.mGraph; - const auto &name = get(RenderGraph::NameTag{}, g, vertID); - visitObject( - vertID, gv.mGraph, - [&](const RasterPass &pass) { - OSS << "RasterPass \"" << name << "\" {\n"; - indent(space); - for (const auto &[name, rasterView] : pass.rasterViews) { - OSS << "RasterView \"" << name << "\" {\n"; - { - INDENT(); - OSS << "slotName: \"" << rasterView.slotName << "\";\n"; - OSS << "accessType: " << getName(rasterView.accessType) << ";\n"; - OSS << "attachmentType: " << getName(rasterView.attachmentType) << ";\n"; - OSS << "loadOp: " << getName(rasterView.loadOp) << ";\n"; - OSS << "storeOp: " << getName(rasterView.storeOp) << ";\n"; - OSS << "clearFlags: " << getName(rasterView.clearFlags) << ";\n"; - const auto &c = rasterView.clearColor; - if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::COLOR)) { - OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; - } else if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { - OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; - } - } - OSS << "}\n"; - } - for (const auto &[name, computeViews] : pass.computeViews) { - OSS << "ComputeViews \"" << name << "\" {\n"; - { - INDENT(); - for (const auto &computeView : computeViews) { - OSS << "ComputeView \"" << computeView.name << "\" {\n"; - { - INDENT(); - OSS << "accessType: " << getName(computeView.accessType) << ";\n"; - OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n"; - const auto &c = computeView.clearValue; - if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) { - OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; - } else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { - OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; - } - } - OSS << "}\n"; - } - } - OSS << "}\n"; - } - }, - [&](const RasterSubpass &subpass) { - std::ignore = subpass; - }, - [&](const ComputeSubpass &subpass) { - std::ignore = subpass; - }, - [&](const ComputePass &pass) { - OSS << "ComputePass \"" << name << "\" {\n"; - indent(space); - for (const auto &[name, computeViews] : pass.computeViews) { - OSS << "ComputeViews \"" << name << "\" {\n"; - { - INDENT(); - for (const auto &computeView : computeViews) { - OSS << "ComputeView \"" << computeView.name << "\" {\n"; - { - INDENT(); - OSS << "accessType: " << getName(computeView.accessType) << ";\n"; - OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n"; - const auto &c = computeView.clearValue; - if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) { - OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; - } else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { - OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; - } - } - OSS << "}\n"; - } - } - OSS << "}\n"; - } - }, - [&](const ResolvePass &pass) { - OSS << "ResolvePass \"" << name << "\" {\n"; - for (const auto &pair : pass.resolvePairs) { - INDENT(); - OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; - } - indent(space); - }, - [&](const CopyPass &pass) { - OSS << "CopyPass \"" << name << "\" {\n"; - for (const auto &pair : pass.copyPairs) { - INDENT(); - OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; - } - indent(space); - }, - [&](const MovePass &pass) { - OSS << "MovePass \"" << name << "\" {\n"; - for (const auto &pair : pass.movePairs) { - INDENT(); - OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; - } - indent(space); - }, - [&](const RaytracePass &pass) { - std::ignore = pass; - OSS << "RaytracePass \"" << name << "\" {\n"; - indent(space); - }, - [&](const RenderQueue &queue) { - OSS << "Queue \"" << name << "\" {\n"; - { - INDENT(); - OSS << "hint: " << getName(queue.hint) << ";\n"; - } - indent(space); - }, - [&](const SceneData &scene) { - std::ignore = scene; - OSS << "Scene \"" << name << "\" {\n"; - indent(space); - }, - [&](const Blit &blit) { - std::ignore = blit; - OSS << "Blit \"" << name << "\";\n"; - }, - [&](const Dispatch &dispatch) { - OSS << "Dispatch \"" << name << "\", [" - << dispatch.threadGroupCountX << ", " - << dispatch.threadGroupCountY << ", " - << dispatch.threadGroupCountZ << "];\n"; - }, - [&](const ccstd::pmr::vector &clearViews) { - OSS << "Clear \"" << name << "\" {\n"; - indent(space); - for (const auto &view : clearViews) { - INDENT(); - OSS << "\"" << view.slotName << "\" {\n"; - { - INDENT(); - OSS << "clearFlags: " << getName(view.clearFlags) << ";\n"; - const auto &c = view.clearColor; - if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::COLOR)) { - OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; - } else if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { - OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; - } - } - OSS << "}\n"; - } - }, - [&](const gfx::Viewport &vp) { - OSS << "Viewport \"" << name << "\" [" - << "left: " << vp.left << ", " - << "top: " << vp.top << ", " - << "width: " << vp.width << ", " - << "height: " << vp.height << ", " - << "minDepth: " << vp.minDepth << ", " - << "maxDepth: " << vp.maxDepth << "]\n"; - }); - } - - void finish_vertex( - RenderGraph::vertex_descriptor vertID, - const AddressableView &gv) const { - std::ignore = gv; - visitObject( - vertID, gv.mGraph, - [&](const RasterPass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const RasterSubpass &subpass) { - std::ignore = subpass; - }, - [&](const ComputeSubpass &subpass) { - std::ignore = subpass; - }, - [&](const ComputePass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const ResolvePass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const CopyPass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const MovePass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const RaytracePass &pass) { - std::ignore = pass; - unindent(space); - OSS << "}\n"; - }, - [&](const RenderQueue &queue) { - std::ignore = queue; - unindent(space); - OSS << "}\n"; - }, - [&](const SceneData &scene) { - std::ignore = scene; - unindent(space); - OSS << "}\n"; - }, - [&](const Blit &blit) { - }, - [&](const Dispatch &dispatch) { - }, - [&](const ccstd::pmr::vector &clear) { - std::ignore = clear; - unindent(space); - OSS << "}\n"; - }, - [&](const gfx::Viewport &clear) { - }); - } - - std::ostringstream &oss; - ccstd::pmr::string &space; -}; - -} // namespace - -ccstd::string RenderGraph::print( - boost::container::pmr::memory_resource *scratch) const { - const auto &rg = *this; - std::ostringstream oss; - ccstd::pmr::string space(scratch); - oss << "\n"; - OSS << "RenderGraph {\n"; - { - INDENT(); - RenderGraphPrintVisitor visitor{ - {}, oss, space}; - AddressableView graphView(rg); - auto colors = rg.colors(scratch); - boost::depth_first_search(graphView, visitor, get(colors, rg)); - } - OSS << "}\n"; - return oss.str(); -} - } // namespace render } // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp new file mode 100644 index 00000000000..dce7e2773fa --- /dev/null +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.cpp @@ -0,0 +1,327 @@ +#include +#include +#include "cocos/renderer/pipeline/custom/RenderCommonNames.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/details/DebugUtils.h" +#include "cocos/renderer/pipeline/custom/details/GraphTypes.h" +#include "cocos/renderer/pipeline/custom/details/GraphView.h" + +namespace cc { + +namespace render { + +namespace { + +const char *getName(const gfx::LoadOp &op) { + switch (op) { + case gfx::LoadOp::LOAD: + return "LOAD"; + case gfx::LoadOp::CLEAR: + return "CLEAR"; + case gfx::LoadOp::DISCARD: + return "DISCARD"; + default: + return "UNKNOWN"; + } + return "UNKNOWN"; +} + +const char *getName(const gfx::StoreOp &op) { + switch (op) { + case gfx::StoreOp::STORE: + return "STORE"; + case gfx::StoreOp::DISCARD: + return "DISCARD"; + default: + return "UNKNOWN"; + } + return "UNKNOWN"; +} + +std::string getName(const gfx::ClearFlagBit &flags) { + std::ostringstream oss; + int count = 0; + if (hasAnyFlags(flags, gfx::ClearFlagBit::COLOR)) { + if (count++) { + oss << "|"; + } + oss << "COLOR"; + } + if (hasAnyFlags(flags, gfx::ClearFlagBit::DEPTH)) { + if (count++) { + oss << "|"; + } + oss << "DEPTH"; + } + if (hasAnyFlags(flags, gfx::ClearFlagBit::STENCIL)) { + if (count++) { + oss << "|"; + } + oss << "STENCIL"; + } + if (flags == gfx::ClearFlagBit::NONE) { + oss << "NONE"; + } + return oss.str(); +} + +struct RenderGraphPrintVisitor : boost::dfs_visitor<> { + void discover_vertex( + RenderGraph::vertex_descriptor vertID, + const AddressableView &gv) const { + const auto &g = gv.mGraph; + const auto &name = get(RenderGraph::NameTag{}, g, vertID); + visitObject( + vertID, gv.mGraph, + [&](const RasterPass &pass) { + OSS << "RasterPass \"" << name << "\" {\n"; + indent(space); + for (const auto &[name, rasterView] : pass.rasterViews) { + OSS << "RasterView \"" << name << "\" {\n"; + { + INDENT(); + OSS << "slotName: \"" << rasterView.slotName << "\";\n"; + OSS << "accessType: " << getName(rasterView.accessType) << ";\n"; + OSS << "attachmentType: " << getName(rasterView.attachmentType) << ";\n"; + OSS << "loadOp: " << getName(rasterView.loadOp) << ";\n"; + OSS << "storeOp: " << getName(rasterView.storeOp) << ";\n"; + OSS << "clearFlags: " << getName(rasterView.clearFlags) << ";\n"; + const auto &c = rasterView.clearColor; + if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::COLOR)) { + OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; + } else if (hasAnyFlags(rasterView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { + OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; + } + } + OSS << "}\n"; + } + for (const auto &[name, computeViews] : pass.computeViews) { + OSS << "ComputeViews \"" << name << "\" {\n"; + { + INDENT(); + for (const auto &computeView : computeViews) { + OSS << "ComputeView \"" << computeView.name << "\" {\n"; + { + INDENT(); + OSS << "accessType: " << getName(computeView.accessType) << ";\n"; + OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n"; + const auto &c = computeView.clearValue; + if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) { + OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; + } else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { + OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; + } + } + OSS << "}\n"; + } + } + OSS << "}\n"; + } + }, + [&](const RasterSubpass &subpass) { + std::ignore = subpass; + }, + [&](const ComputeSubpass &subpass) { + std::ignore = subpass; + }, + [&](const ComputePass &pass) { + OSS << "ComputePass \"" << name << "\" {\n"; + indent(space); + for (const auto &[name, computeViews] : pass.computeViews) { + OSS << "ComputeViews \"" << name << "\" {\n"; + { + INDENT(); + for (const auto &computeView : computeViews) { + OSS << "ComputeView \"" << computeView.name << "\" {\n"; + { + INDENT(); + OSS << "accessType: " << getName(computeView.accessType) << ";\n"; + OSS << "clearFlags: " << getName(computeView.clearFlags) << ";\n"; + const auto &c = computeView.clearValue; + if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::COLOR)) { + OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; + } else if (hasAnyFlags(computeView.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { + OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; + } + } + OSS << "}\n"; + } + } + OSS << "}\n"; + } + }, + [&](const ResolvePass &pass) { + OSS << "ResolvePass \"" << name << "\" {\n"; + for (const auto &pair : pass.resolvePairs) { + INDENT(); + OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; + } + indent(space); + }, + [&](const CopyPass &pass) { + OSS << "CopyPass \"" << name << "\" {\n"; + for (const auto &pair : pass.copyPairs) { + INDENT(); + OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; + } + indent(space); + }, + [&](const MovePass &pass) { + OSS << "MovePass \"" << name << "\" {\n"; + for (const auto &pair : pass.movePairs) { + INDENT(); + OSS << "source: \"" << pair.source << "\", target: \"" << pair.target << "\"\n"; + } + indent(space); + }, + [&](const RaytracePass &pass) { + std::ignore = pass; + OSS << "RaytracePass \"" << name << "\" {\n"; + indent(space); + }, + [&](const RenderQueue &queue) { + OSS << "Queue \"" << name << "\" {\n"; + { + INDENT(); + OSS << "hint: " << getName(queue.hint) << ";\n"; + } + indent(space); + }, + [&](const SceneData &scene) { + std::ignore = scene; + OSS << "Scene \"" << name << "\" {\n"; + indent(space); + }, + [&](const Blit &blit) { + std::ignore = blit; + OSS << "Blit \"" << name << "\";\n"; + }, + [&](const Dispatch &dispatch) { + OSS << "Dispatch \"" << name << "\", [" + << dispatch.threadGroupCountX << ", " + << dispatch.threadGroupCountY << ", " + << dispatch.threadGroupCountZ << "];\n"; + }, + [&](const ccstd::pmr::vector &clearViews) { + OSS << "Clear \"" << name << "\" {\n"; + indent(space); + for (const auto &view : clearViews) { + INDENT(); + OSS << "\"" << view.slotName << "\" {\n"; + { + INDENT(); + OSS << "clearFlags: " << getName(view.clearFlags) << ";\n"; + const auto &c = view.clearColor; + if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::COLOR)) { + OSS << "clearColor: [" << c.x << ", " << c.y << ", " << c.z << ", " << c.z << "];\n"; + } else if (hasAnyFlags(view.clearFlags, gfx::ClearFlagBit::DEPTH_STENCIL)) { + OSS << "clearColor: [" << c.x << ", " << c.y << "];\n"; + } + } + OSS << "}\n"; + } + }, + [&](const gfx::Viewport &vp) { + OSS << "Viewport \"" << name << "\" [" + << "left: " << vp.left << ", " + << "top: " << vp.top << ", " + << "width: " << vp.width << ", " + << "height: " << vp.height << ", " + << "minDepth: " << vp.minDepth << ", " + << "maxDepth: " << vp.maxDepth << "]\n"; + }); + } + + void finish_vertex( + RenderGraph::vertex_descriptor vertID, + const AddressableView &gv) const { + std::ignore = gv; + visitObject( + vertID, gv.mGraph, + [&](const RasterPass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const RasterSubpass &subpass) { + std::ignore = subpass; + }, + [&](const ComputeSubpass &subpass) { + std::ignore = subpass; + }, + [&](const ComputePass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const ResolvePass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const CopyPass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const MovePass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const RaytracePass &pass) { + std::ignore = pass; + unindent(space); + OSS << "}\n"; + }, + [&](const RenderQueue &queue) { + std::ignore = queue; + unindent(space); + OSS << "}\n"; + }, + [&](const SceneData &scene) { + std::ignore = scene; + unindent(space); + OSS << "}\n"; + }, + [&](const Blit &blit) { + }, + [&](const Dispatch &dispatch) { + }, + [&](const ccstd::pmr::vector &clear) { + std::ignore = clear; + unindent(space); + OSS << "}\n"; + }, + [&](const gfx::Viewport &clear) { + }); + } + + std::ostringstream &oss; + ccstd::pmr::string &space; +}; + +} // namespace + +ccstd::string RenderGraph::print( + boost::container::pmr::memory_resource *scratch) const { + const auto &rg = *this; + std::ostringstream oss; + ccstd::pmr::string space(scratch); + oss << "\n"; + OSS << "RenderGraph {\n"; + { + INDENT(); + RenderGraphPrintVisitor visitor{ + {}, oss, space}; + AddressableView graphView(rg); + auto colors = rg.colors(scratch); + boost::depth_first_search(graphView, visitor, get(colors, rg)); + } + OSS << "}\n"; + return oss.str(); +} + +} // namespace render + +} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h index 6b43d7ac71d..1022adac559 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h @@ -9,6 +9,36 @@ namespace cc { namespace render { +inline LayoutGraphData::vertex_descriptor getSubpassOrPassID( + RenderGraph::vertex_descriptor vertID, + const RenderGraph &rg, const LayoutGraphData &lg) { + const auto queueID = parent(vertID, rg); + CC_ENSURES(queueID != RenderGraph::null_vertex()); + const auto subpassOrPassID = parent(queueID, rg); + CC_ENSURES(subpassOrPassID != RenderGraph::null_vertex()); + const auto passID = parent(subpassOrPassID, rg); + + auto layoutID = LayoutGraphData::null_vertex(); + if (passID == RenderGraph::null_vertex()) { // single render pass + const auto &layoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID); + CC_ENSURES(!layoutName.empty()); + layoutID = locate(LayoutGraphData::null_vertex(), layoutName, lg); + } else { // render pass + const auto &passLayoutName = get(RenderGraph::LayoutTag{}, rg, passID); + CC_ENSURES(!passLayoutName.empty()); + const auto passLayoutID = locate(LayoutGraphData::null_vertex(), passLayoutName, lg); + CC_ENSURES(passLayoutID != LayoutGraphData::null_vertex()); + + const auto &subpassLayoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID); + CC_ENSURES(!subpassLayoutName.empty()); + const auto subpassLayoutID = locate(passLayoutID, subpassLayoutName, lg); + CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex()); + layoutID = subpassLayoutID; + } + CC_ENSURES(layoutID != LayoutGraphData::null_vertex()); + return layoutID; +} + inline std::tuple addRenderPassVertex( RenderGraph &renderGraph, const LayoutGraphData &layoutGraph, diff --git a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp index faa14472d23..b2f7e396333 100644 --- a/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeSceneCulling.cpp @@ -1,16 +1,11 @@ -#include "LayoutGraphGraphs.h" -#include "NativePipelineTypes.h" -#include "NativeUtils.h" -#include "RenderGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" +#include "cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" +#include "cocos/renderer/pipeline/custom/details/Range.h" #include "cocos/scene/Octree.h" #include "cocos/scene/RenderScene.h" #include "cocos/scene/Skybox.h" #include "cocos/scene/SpotLight.h" -#include "details/GslUtils.h" -#include "details/Range.h" -#include "pipeline/custom/LayoutGraphTypes.h" -#include "pipeline/custom/NativeUtils.h" -#include "pipeline/custom/RenderCommonTypes.h" namespace cc { @@ -406,7 +401,7 @@ void SceneCulling::fillRenderQueues( CC_EXPECTS(targetID < renderQueues.size()); auto& nativeQueue = renderQueues[targetID]; CC_EXPECTS(nativeQueue.empty()); - + // skybox const auto* camera = sceneData.camera; CC_EXPECTS(camera); diff --git a/native/cocos/renderer/pipeline/custom/NativeSetter.cpp b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp new file mode 100644 index 00000000000..b7951a7c869 --- /dev/null +++ b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp @@ -0,0 +1,129 @@ +#include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h" +#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" +#include "cocos/renderer/pipeline/custom/NativeUtils.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" +#include "cocos/scene/RenderScene.h" +#include "cocos/scene/SpotLight.h" + +namespace cc { + +namespace render { + +void NativeSetter::setMat4(const ccstd::string &name, const Mat4 &mat) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setMat4Impl(data, *layoutGraph, name, mat); +} + +void NativeSetter::setQuaternion(const ccstd::string &name, const Quaternion &quat) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setQuaternionImpl(data, *layoutGraph, name, quat); +} + +void NativeSetter::setColor(const ccstd::string &name, const gfx::Color &color) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setColorImpl(data, *layoutGraph, name, color); +} + +void NativeSetter::setVec4(const ccstd::string &name, const Vec4 &vec) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4Impl(data, *layoutGraph, name, vec); +} + +void NativeSetter::setVec2(const ccstd::string &name, const Vec2 &vec) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec2Impl(data, *layoutGraph, name, vec); +} + +void NativeSetter::setFloat(const ccstd::string &name, float v) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setFloatImpl(data, *layoutGraph, name, v); +} + +void NativeSetter::setArrayBuffer(const ccstd::string &name, const ArrayBuffer *buffer) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setArrayBufferImpl(data, *layoutGraph, name, *buffer); +} + +void NativeSetter::setBuffer(const ccstd::string &name, gfx::Buffer *buffer) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setBufferImpl(data, *layoutGraph, name, buffer); +} + +void NativeSetter::setTexture(const ccstd::string &name, gfx::Texture *texture) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setTextureImpl(data, *layoutGraph, name, texture); +} + +void NativeSetter::setReadWriteBuffer(const ccstd::string &name, gfx::Buffer *buffer) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setReadWriteBufferImpl(data, *layoutGraph, name, buffer); +} + +void NativeSetter::setReadWriteTexture(const ccstd::string &name, gfx::Texture *texture) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setReadWriteTextureImpl(data, *layoutGraph, name, texture); +} + +void NativeSetter::setSampler(const ccstd::string &name, gfx::Sampler *sampler) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setSamplerImpl(data, *layoutGraph, name, sampler); +} + +void NativeSetter::setVec4ArraySize(const ccstd::string &name, uint32_t sz) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4ArraySizeImpl(data, *layoutGraph, name, sz); +} + +void NativeSetter::setVec4ArrayElem(const ccstd::string &name, const cc::Vec4 &vec, uint32_t id) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setVec4ArrayElemImpl(data, *layoutGraph, name, vec, id); +} + +void NativeSetter::setMat4ArraySize(const ccstd::string &name, uint32_t sz) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setMat4ArraySizeImpl(data, *layoutGraph, name, sz); +} + +void NativeSetter::setMat4ArrayElem(const ccstd::string &name, const cc::Mat4 &mat, uint32_t id) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setMat4ArrayElemImpl(data, *layoutGraph, name, mat, id); +} + +void NativeSetter::setBuiltinCameraConstants(const scene::Camera *camera) { + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setCameraUBOValues( + *camera, + *layoutGraph, + *pipelineRuntime->getPipelineSceneData(), + camera->getScene()->getMainLight(), data); +} + +void NativeSetter::setBuiltinDirectionalLightViewConstants( + const scene::DirectionalLight *light, uint32_t level) { + CC_EXPECTS(light); + auto *device = pipelineRuntime->getDevice(); + const auto &sceneData = *pipelineRuntime->getPipelineSceneData(); + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setShadowUBOLightView(device, *layoutGraph, sceneData, *light, level, data); +} + +void NativeSetter::setBuiltinSpotLightViewConstants(const scene::SpotLight *light) { + CC_EXPECTS(light); + auto *device = pipelineRuntime->getDevice(); + const auto &sceneData = *pipelineRuntime->getPipelineSceneData(); + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setShadowUBOLightView(device, *layoutGraph, sceneData, *light, 0, data); +} + +void NativeSetter::setBuiltinShadowMapConstants( + const scene::DirectionalLight *light) { + CC_EXPECTS(light); + auto *device = pipelineRuntime->getDevice(); + const auto &sceneData = *pipelineRuntime->getPipelineSceneData(); + auto &data = get(RenderGraph::DataTag{}, *renderGraph, nodeID); + setShadowUBOView(*device, *layoutGraph, sceneData, *light, data); +} + +} // namespace render + +} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp index 75af2336a16..480ade58e1d 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp @@ -1,98 +1,12 @@ -#include "NativeUtils.h" -#include "LayoutGraphGraphs.h" -#include "NativePipelineTypes.h" -#include "RenderGraphGraphs.h" -#include "cocos/application/ApplicationManager.h" -#include "cocos/core/Root.h" -#include "details/GslUtils.h" +#include "cocos/renderer/pipeline/custom/NativeUtils.h" +#include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" +#include "cocos/renderer/pipeline/custom/RenderGraphGraphs.h" +#include "cocos/renderer/pipeline/custom/details/GslUtils.h" namespace cc { -namespace render { - -void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]) { - auto minX = static_cast(viewport.x); - auto maxX = static_cast(viewport.x + viewport.z); - auto minY = static_cast(viewport.y); - auto maxY = static_cast(viewport.y + viewport.w); - if (device.getCapabilities().screenSpaceSignY > 0) { - std::swap(minY, maxY); - } - int n = 0; - vbData[n++] = -1.0F; - vbData[n++] = -1.0F; - vbData[n++] = minX; // uv - vbData[n++] = maxY; - vbData[n++] = 1.0F; - vbData[n++] = -1.0F; - vbData[n++] = maxX; - vbData[n++] = maxY; - vbData[n++] = -1.0F; - vbData[n++] = 1.0F; - vbData[n++] = minX; - vbData[n++] = minY; - vbData[n++] = 1.0F; - vbData[n++] = 1.0F; - vbData[n++] = maxX; - vbData[n++] = minY; -} -// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter) { - const auto &root = *Root::getInstance(); - const auto shadingWidth = static_cast(width); - const auto shadingHeight = static_cast(height); - setter.setVec4( - "cc_time", - Vec4( - root.getCumulativeTime(), - root.getFrameTime(), - static_cast(CC_CURRENT_ENGINE()->getTotalFrames()), - 0.0F)); - - setter.setVec4( - "cc_screenSize", - Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight)); - setter.setVec4( - "cc_nativeSize", - Vec4(shadingWidth, shadingHeight, 1.0F / shadingWidth, 1.0F / shadingHeight)); -#if 0 - const auto *debugView = root.getDebugView(); - if (debugView) { - setter.setVec4( - "cc_debug_view_mode", - Vec4(static_cast(debugView->getSingleMode()), - debugView->isLightingWithAlbedo() ? 1.0F : 0.0F, - debugView->isCsmLayerColoration() ? 1.0F : 0.0F, - 0.0F)); - Vec4 debugPackVec{}; - for (auto i = static_cast(pipeline::DebugViewCompositeType::DIRECT_DIFFUSE); - i < static_cast(pipeline::DebugViewCompositeType::MAX_BIT_COUNT); ++i) { - const auto idx = i % 4; - (&debugPackVec.x)[idx] = debugView->isCompositeModeEnabled(i) ? 1.0F : 0.0F; - const auto packIdx = static_cast(floor(static_cast(i) / 4.0F)); - if (idx == 3) { - std::string name("cc_debug_view_composite_pack_"); - name.append(std::to_string(packIdx + 1)); - setter.setVec4(name, debugPackVec); - } - } - } else { - setter.setVec4("cc_debug_view_mode", Vec4(0.0F, 1.0F, 0.0F, 0.0F)); - Vec4 debugPackVec{}; - for (auto i = static_cast(pipeline::DebugViewCompositeType::DIRECT_DIFFUSE); - i < static_cast(pipeline::DebugViewCompositeType::MAX_BIT_COUNT); ++i) { - const auto idx = i % 4; - (&debugPackVec.x)[idx] = 1.0F; - const auto packIdx = static_cast(floor(i / 4.0)); - if (idx == 3) { - std::string name("cc_debug_view_composite_pack_"); - name.append(std::to_string(packIdx + 1)); - setter.setVec4(name, debugPackVec); - } - } - } -#endif -} +namespace render { namespace { @@ -225,35 +139,6 @@ void setSamplerImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::st data.samplers[nameID.value] = sampler; } -LayoutGraphData::vertex_descriptor getSubpassOrPassID( - RenderGraph::vertex_descriptor vertID, - const RenderGraph &rg, const LayoutGraphData &lg) { - const auto queueID = parent(vertID, rg); - CC_ENSURES(queueID != RenderGraph::null_vertex()); - const auto subpassOrPassID = parent(queueID, rg); - CC_ENSURES(subpassOrPassID != RenderGraph::null_vertex()); - const auto passID = parent(subpassOrPassID, rg); - - auto layoutID = LayoutGraphData::null_vertex(); - if (passID == RenderGraph::null_vertex()) { // single render pass - const auto &layoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID); - CC_ENSURES(!layoutName.empty()); - layoutID = locate(LayoutGraphData::null_vertex(), layoutName, lg); - } else { // render pass - const auto &passLayoutName = get(RenderGraph::LayoutTag{}, rg, passID); - CC_ENSURES(!passLayoutName.empty()); - const auto passLayoutID = locate(LayoutGraphData::null_vertex(), passLayoutName, lg); - CC_ENSURES(passLayoutID != LayoutGraphData::null_vertex()); - - const auto &subpassLayoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID); - CC_ENSURES(!subpassLayoutName.empty()); - const auto subpassLayoutID = locate(passLayoutID, subpassLayoutName, lg); - CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex()); - layoutID = subpassLayoutID; - } - CC_ENSURES(layoutID != LayoutGraphData::null_vertex()); - return layoutID; -} - } // namespace render + } // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.h b/native/cocos/renderer/pipeline/custom/NativeUtils.h index 620aa64b3e2..e1ddf40a79f 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.h @@ -1,8 +1,8 @@ #pragma once #include "cocos/core/ArrayBuffer.h" #include "cocos/math/Vec4.h" -#include "cocos/renderer/pipeline/custom/LayoutGraphTypes.h" -#include "cocos/renderer/pipeline/custom/RenderGraphTypes.h" +#include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h" +#include "cocos/renderer/pipeline/custom/RenderGraphFwd.h" #include "cocos/renderer/pipeline/custom/RenderInterfaceFwd.h" namespace cc { @@ -11,9 +11,6 @@ class Device; } namespace render { -void setupQuadVertexBuffer(gfx::Device &device, const Vec4 &viewport, float vbData[16]); -void updateRasterPassConstants(uint32_t width, uint32_t height, Setter &setter); - void setMat4Impl( RenderData &data, const LayoutGraphData &lg, std::string_view name, const cc::Mat4 &v); @@ -56,11 +53,6 @@ void setReadWriteTextureImpl(RenderData &data, const LayoutGraphData &lg, const void setSamplerImpl(RenderData &data, const LayoutGraphData &lg, const ccstd::string &name, gfx::Sampler *sampler); -// Implementation -LayoutGraphData::vertex_descriptor getSubpassOrPassID( - RenderGraph::vertex_descriptor vertID, - const RenderGraph &rg, const LayoutGraphData &lg); - } // namespace render } // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index fea8e265f87..b0ff54e7d8c 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -154,6 +154,7 @@ enum class SceneFlags : uint32_t { DRAW_INSTANCING = 0x800, DRAW_NON_INSTANCING = 0x1000, REFLECTION_PROBE = 0x2000, + GPU_DRIVEN = 0x4000, ALL = 0xFFFFFFFF, }; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 0c40193d4a1..25e9e786b69 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -450,6 +450,13 @@ class Setter : public RenderNode { * @param name @en descriptor name in shader. @zh 填写着色器中的描述符(descriptor)名字 */ virtual void setSampler(const ccstd::string &name, gfx::Sampler *sampler) = 0; + virtual void setBuiltinCameraConstants(const scene::Camera *camera) = 0; + virtual void setBuiltinShadowMapConstants(const scene::DirectionalLight *light) = 0; + virtual void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light, uint32_t level) = 0; + virtual void setBuiltinSpotLightViewConstants(const scene::SpotLight *light) = 0; + void setBuiltinDirectionalLightViewConstants(const scene::DirectionalLight *light) { + setBuiltinDirectionalLightViewConstants(light, 0); + } }; /** @@ -473,6 +480,9 @@ class RenderQueueBuilder : public Setter { * @param sceneFlags @en Rendering flags of the scene @zh 场景渲染标志位 */ virtual void addSceneOfCamera(scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) = 0; + virtual void addScene(const scene::Camera *camera, SceneFlags sceneFlags) = 0; + virtual void addSceneCulledByDirectionalLight(const scene::Camera *camera, SceneFlags sceneFlags, scene::DirectionalLight *light, uint32_t level) = 0; + virtual void addSceneCulledBySpotLight(const scene::Camera *camera, SceneFlags sceneFlags, scene::SpotLight *light) = 0; /** * @en Render a full-screen quad. * @zh 渲染全屏四边形 From 85f239b4971b5a785a94ee92cc7f47faec383bb1 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 30 Jun 2023 16:57:50 +0800 Subject: [PATCH 37/57] cleanup --- native/cocos/renderer/pipeline/custom/NativeUtils.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.h b/native/cocos/renderer/pipeline/custom/NativeUtils.h index e1ddf40a79f..7e0a17834ec 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.h @@ -6,9 +6,7 @@ #include "cocos/renderer/pipeline/custom/RenderInterfaceFwd.h" namespace cc { -namespace gfx { -class Device; -} + namespace render { void setMat4Impl( From d79394d9010d43309954e07124274fd04cce4a1c Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 30 Jun 2023 17:01:14 +0800 Subject: [PATCH 38/57] format --- cocos/rendering/custom/web-pipeline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 1a30d49f8f4..f66023c1fd0 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1773,7 +1773,7 @@ export class WebPipeline implements BasicPipeline { this.execute(); this.endFrame(); } - addRenderPassImpl (width: number, height: number, layoutName: string, count = 1, quality = 0): BasicMultisampleRenderPassBuilder { + addRenderPassImpl (width: number, height: number, layoutName: string, count = 1, quality = 0): BasicMultisampleRenderPassBuilder { if (DEBUG) { const stageId = this.layoutGraph.locateChild(this.layoutGraph.nullVertex(), layoutName); assert(stageId !== 0xFFFFFFFF); From 6dabe6fb0280e7339af592b460f6daac29f56f7f Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 5 Jul 2023 16:19:52 +0800 Subject: [PATCH 39/57] add resource added --- cocos/rendering/custom/pipeline.ts | 25 +++++++- cocos/rendering/custom/web-pipeline.ts | 33 +++++++++- .../pipeline/custom/NativePipeline.cpp | 61 +++++++++++++++++++ .../pipeline/custom/NativePipelineTypes.h | 2 + .../pipeline/custom/RenderInterfaceTypes.h | 2 + 5 files changed, 120 insertions(+), 3 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index b71e1e83be6..f54a721df84 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -32,12 +32,12 @@ import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; import { DirectionalLight } from '../../render-scene/scene/directional-light'; import { GeometryRenderer } from '../geometry-renderer'; -import { Buffer, BufferInfo, ClearFlagBit, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, LoadOp, PipelineState, Rect, ResolveMode, Sampler, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureInfo, Viewport } from '../../gfx'; +import { Buffer, BufferInfo, ClearFlagBit, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, LoadOp, PipelineState, Rect, ResolveMode, SampleCount, Sampler, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureInfo, Viewport } from '../../gfx'; import { GlobalDSManager } from '../global-descriptor-set-manager'; import { Mat4, Quat, Vec2, Vec4 } from '../../core/math'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; +import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Model } from '../../render-scene/scene'; import { SpotLight } from '../../render-scene/scene/spot-light'; @@ -673,6 +673,27 @@ export interface BasicPipeline extends PipelineRuntime { width: number, height: number, format?: Format): void; + addResource ( + name: string, + dimension: ResourceDimension, + format: Format, + width: number, + height: number, + depth: number, + arraySize: number, + mipLevels: number, + sampleCount: SampleCount, + flags: ResourceFlags, + residency: ResourceResidency): number; + updateResource ( + name: string, + format: Format, + width: number, + height: number, + depth: number, + arraySize: number, + mipLevels: number, + sampleCount: SampleCount): void; /** * @engineInternal * @en Begin rendering one frame diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index f66023c1fd0..84a90f1369f 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -25,7 +25,7 @@ /* eslint-disable max-len */ import { systemInfo } from 'pal/system-info'; import { DEBUG } from 'internal:constants'; -import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, ResolveMode } from '../../gfx'; +import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, ResolveMode, SampleCount } from '../../gfx'; import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy } from '../../core'; import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; @@ -1376,6 +1376,37 @@ export class WebPipeline implements BasicPipeline { desc.width = width; desc.height = height; } + addResource (name: string, dimension: ResourceDimension, format: Format, width: number, height: number, depth: number, arraySize: number, mipLevels: number, sampleCount: SampleCount, flags: ResourceFlags, residency: ResourceResidency): number { + const desc = new ResourceDesc(); + desc.dimension = dimension; + desc.width = width; + desc.height = height; + desc.depthOrArraySize = dimension === ResourceDimension.TEXTURE3D ? depth : arraySize; + desc.mipLevels = mipLevels; + desc.format = format; + desc.sampleCount = sampleCount; + desc.flags = flags; + return this._resourceGraph.addVertex( + ResourceGraphValue.Managed, + new ManagedResource(), + name, desc, + new ResourceTraits(residency), + new ResourceStates(), + new SamplerInfo(Filter.LINEAR, Filter.LINEAR, Filter.NONE, Address.CLAMP, Address.CLAMP, Address.CLAMP), + ); + } + updateResource (name: string, format: Format, width: number, height: number, depth: number, arraySize: number, mipLevels: number, sampleCount: SampleCount): void { + const resId = this.resourceGraph.vertex(name); + const desc = this.resourceGraph.getDesc(resId); + desc.width = width; + desc.height = height; + desc.depthOrArraySize = desc.dimension === ResourceDimension.TEXTURE3D ? depth : arraySize; + desc.mipLevels = mipLevels; + if (format !== Format.UNKNOWN) { + desc.format = format; + } + desc.sampleCount = sampleCount; + } public containsResource (name: string): boolean { return this._resourceGraph.contains(name); } diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 5614fa51793..846ae2f986a 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -206,6 +206,67 @@ uint32_t NativePipeline::addDepthStencil(const ccstd::string &name, gfx::Format resourceGraph); } +uint32_t NativePipeline::addResource(const ccstd::string& name, ResourceDimension dimension, + gfx::Format format, + uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, + gfx::SampleCount sampleCount, ResourceFlags flags, ResourceResidency residency) { + ResourceDesc desc{ + dimension, + 0, + width, + height, + static_cast(dimension == ResourceDimension::TEXTURE3D ? depth : arraySize), + static_cast(mipLevels), + format, + sampleCount, + gfx::TextureFlagBit::NONE, + flags, + }; + return addVertex( + ManagedTextureTag{}, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple(desc), + std::forward_as_tuple(ResourceTraits{residency}), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + resourceGraph); +} + +void NativePipeline::updateResource(const ccstd::string& name, gfx::Format format, + uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, // NOLINT(bugprone-easily-swappable-parameters) + gfx::SampleCount sampleCount) { + auto resID = findVertex(ccstd::pmr::string(name, get_allocator()), resourceGraph); + if (resID == ResourceGraph::null_vertex()) { + return; + } + auto &desc = get(ResourceGraph::DescTag{}, resourceGraph, resID); + + // update format + if (format == gfx::Format::UNKNOWN) { + format = desc.format; + } + visitObject( + resID, resourceGraph, + [&](ManagedTexture &tex) { + uint32_t depthOrArraySize = static_cast( + desc.dimension == ResourceDimension::TEXTURE3D ? depth : arraySize); + bool invalidate = + std::forward_as_tuple(desc.width, desc.height, desc.depthOrArraySize, desc.mipLevels, desc.format, desc.sampleCount) != + std::forward_as_tuple(width, height, depthOrArraySize, mipLevels, format, sampleCount); + if (invalidate) { + desc.width = width; + desc.height = height; + desc.depthOrArraySize = depthOrArraySize; + desc.mipLevels = mipLevels; + desc.format = format; + desc.sampleCount = sampleCount; + resourceGraph.invalidatePersistentRenderPassAndFramebuffer(tex.texture.get()); + } + }, + [](const auto & /*res*/) {}); +} + // NOLINTNEXTLINE uint32_t NativePipeline::addStorageTexture(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) { ResourceDesc desc{}; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index d4686c0ccd4..773f8d960e7 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -1282,6 +1282,8 @@ class NativePipeline final : public Pipeline { uint32_t addDepthStencil(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, ResourceResidency residency) override; void updateRenderTarget(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) override; void updateDepthStencil(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) override; + uint32_t addResource(const ccstd::string &name, ResourceDimension dimension, gfx::Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, gfx::SampleCount sampleCount, ResourceFlags flags, ResourceResidency residency) override; + void updateResource(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, gfx::SampleCount sampleCount) override; void beginFrame() override; void update(const scene::Camera *camera) override; void endFrame() override; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 25e9e786b69..aa028273cd8 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -760,6 +760,8 @@ class BasicPipeline : public PipelineRuntime { * @param format @en Format of the resource @zh 资源的格式 */ virtual void updateDepthStencil(const ccstd::string &name, uint32_t width, uint32_t height, gfx::Format format) = 0; + virtual uint32_t addResource(const ccstd::string &name, ResourceDimension dimension, gfx::Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, gfx::SampleCount sampleCount, ResourceFlags flags, ResourceResidency residency) = 0; + virtual void updateResource(const ccstd::string &name, gfx::Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t arraySize, uint32_t mipLevels, gfx::SampleCount sampleCount) = 0; /** * @engineInternal * @en Begin rendering one frame From 10f863902158dddab4a412bbc24e9a5cff04535a Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 5 Jul 2023 16:58:33 +0800 Subject: [PATCH 40/57] add sortedVertices for GPU driven --- cocos/rendering/custom/render-graph.ts | 2 ++ .../pipeline/custom/NativePipeline.cpp | 10 +++---- .../pipeline/custom/NativeRenderGraph.cpp | 30 +++++++++---------- .../pipeline/custom/NativeRenderGraphUtils.h | 22 ++++++++++++-- .../pipeline/custom/RenderGraphTypes.cpp | 6 ++-- .../pipeline/custom/RenderGraphTypes.h | 1 + 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index afbb675ef8d..93e33253156 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -1656,6 +1656,7 @@ export class RenderGraph implements BidirectionalGraph clear (): void { // Members this.index.clear(); + this.sortedVertices.length = 0; // ComponentGraph this._names.length = 0; this._layoutNodes.length = 0; @@ -2267,4 +2268,5 @@ export class RenderGraph implements BidirectionalGraph readonly _data: RenderData[] = []; readonly _valid: boolean[] = []; readonly index: Map = new Map(); + readonly sortedVertices: number[] = []; } diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 846ae2f986a..c52b7276a3e 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -607,7 +607,7 @@ void NativePipeline::addResolvePass(const ccstd::vector &resolvePai pass.resolvePairs.emplace_back(pair); } std::string_view name("Resolve"); - addVertex( + addVertex2( ResolveTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -619,7 +619,7 @@ void NativePipeline::addResolvePass(const ccstd::vector &resolvePai // NOLINTNEXTLINE ComputePassBuilder *NativePipeline::addComputePass(const ccstd::string &passName) { - auto passID = addVertex( + auto passID = addVertex2( ComputeTag{}, std::forward_as_tuple(passName), std::forward_as_tuple(passName), @@ -640,7 +640,7 @@ void NativePipeline::addMovePass(const ccstd::vector &movePairs) { pass.movePairs.emplace_back(pair); } std::string_view name("Move"); - addVertex( + addVertex2( MoveTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -657,7 +657,7 @@ void NativePipeline::addCopyPass(const ccstd::vector ©Pairs) { pass.copyPairs.emplace_back(pair); } std::string_view name("Copy"); - addVertex( + addVertex2( CopyTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -675,7 +675,7 @@ void NativePipeline::addUploadPass(ccstd::vector &uploadPairs) { } uploadPairs.clear(); std::string_view name("Upload"); - addVertex( + addVertex2( CopyTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 28b9be1176b..28fa3ed130e 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -495,7 +495,7 @@ RenderQueueBuilder *NativeRenderSubpassBuilderImpl::addQueue( const auto phaseLayoutID = locate(layoutID, phaseName, *layoutGraph); CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); - auto queueID = addVertex( + auto queueID = addVertex2( QueueTag{}, std::forward_as_tuple(phaseName), std::forward_as_tuple(phaseName), @@ -635,7 +635,7 @@ ComputeQueueBuilder *NativeComputeSubpassBuilder::addQueue(const ccstd::string & const auto phaseLayoutID = locate(layoutID, phaseName, *layoutGraph); CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); - auto queueID = addVertex( + auto queueID = addVertex2( QueueTag{}, std::forward_as_tuple(phaseName), std::forward_as_tuple(phaseName), @@ -651,7 +651,7 @@ void NativeRenderQueueBuilder::addSceneOfCamera( scene::Camera *camera, LightInfo light, SceneFlags sceneFlags) { const auto *pLight = light.light.get(); SceneData scene(camera->getScene(), camera, sceneFlags, light); - auto sceneID = addVertex( + auto sceneID = addVertex2( SceneTag{}, std::forward_as_tuple("Camera"), std::forward_as_tuple(), @@ -696,7 +696,7 @@ void NativeRenderQueueBuilder::addSceneOfCamera( void NativeRenderQueueBuilder::addScene(const scene::Camera *camera, SceneFlags sceneFlags) { SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{}); - auto sceneID = addVertex( + auto sceneID = addVertex2( SceneTag{}, std::forward_as_tuple("Scene"), std::forward_as_tuple(), @@ -714,7 +714,7 @@ void NativeRenderQueueBuilder::addSceneCulledByDirectionalLight( CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, level}); - auto sceneID = addVertex( + auto sceneID = addVertex2( SceneTag{}, std::forward_as_tuple("Scene"), std::forward_as_tuple(), @@ -732,7 +732,7 @@ void NativeRenderQueueBuilder::addSceneCulledBySpotLight( CC_EXPECTS(light->getType() != scene::LightType::UNKNOWN); SceneData data(camera->getScene(), camera, sceneFlags, LightInfo{light, 0}); - auto sceneID = addVertex( + auto sceneID = addVertex2( SceneTag{}, std::forward_as_tuple("Scene"), std::forward_as_tuple(), @@ -746,7 +746,7 @@ void NativeRenderQueueBuilder::addSceneCulledBySpotLight( void NativeRenderQueueBuilder::addFullscreenQuad( Material *material, uint32_t passID, SceneFlags sceneFlags) { std::string_view name = "FullscreenQuad"; - auto drawID = addVertex( + auto drawID = addVertex2( BlitTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -761,7 +761,7 @@ void NativeRenderQueueBuilder::addCameraQuad( scene::Camera *camera, cc::Material *material, uint32_t passID, SceneFlags sceneFlags) { std::string_view name = "CameraQuad"; - auto drawID = addVertex( + auto drawID = addVertex2( BlitTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -800,7 +800,7 @@ void NativeRenderQueueBuilder::clearRenderTarget(const ccstd::string &name, cons ccstd::pmr::vector clears(renderGraph->get_allocator()); clears.emplace_back(name.c_str(), gfx::ClearFlagBit::COLOR, color); - auto clearID = addVertex( + auto clearID = addVertex2( ClearTag{}, std::forward_as_tuple("ClearRenderTarget"), std::forward_as_tuple(), @@ -818,7 +818,7 @@ void NativeRenderQueueBuilder::setViewport(const gfx::Viewport &viewport) { void NativeRenderQueueBuilder::addCustomCommand(std::string_view customBehavior) { std::string_view name = "FullscreenQuad"; - auto drawID = addVertex( + auto drawID = addVertex2( BlitTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -843,7 +843,7 @@ RenderQueueBuilder *NativeRenderPassBuilder::addQueue( const auto phaseLayoutID = locate(layoutID, phaseName, *layoutGraph); CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); - auto queueID = addVertex( + auto queueID = addVertex2( QueueTag{}, std::forward_as_tuple(phaseName), std::forward_as_tuple(phaseName), @@ -905,7 +905,7 @@ ComputeSubpassBuilder *NativeRenderPassBuilder::addComputeSubpass(const ccstd::s ComputeSubpass subpass(subpassIndex, renderGraph->get_allocator()); - auto subpassID = addVertex( + auto subpassID = addVertex2( ComputeSubpassTag{}, std::forward_as_tuple(subpassName), std::forward_as_tuple(subpassName), @@ -1040,7 +1040,7 @@ RenderQueueBuilder *NativeMultisampleRenderPassBuilder::addQueue( const auto phaseLayoutID = locate(subpassLayoutID, phaseName, *layoutGraph); CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); - auto queueID = addVertex( + auto queueID = addVertex2( QueueTag{}, std::forward_as_tuple(phaseName), std::forward_as_tuple(phaseName), @@ -1106,7 +1106,7 @@ void NativeComputeQueueBuilder::addDispatch( uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ, Material *material, uint32_t passID) { std::string_view name("Dispatch"); - addVertex( + addVertex2( DispatchTag{}, std::forward_as_tuple(name), std::forward_as_tuple(), @@ -1208,7 +1208,7 @@ ComputeQueueBuilder *NativeComputePassBuilder::addQueue(const ccstd::string &pha const auto phaseLayoutID = locate(layoutID, phaseName, *layoutGraph); CC_ENSURES(phaseLayoutID != LayoutGraphData::null_vertex()); - auto queueID = addVertex( + auto queueID = addVertex2( QueueTag{}, std::forward_as_tuple(phaseName), std::forward_as_tuple(phaseName), diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h index 1022adac559..82541e18db0 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h @@ -9,6 +9,24 @@ namespace cc { namespace render { +template +RenderGraph::vertex_descriptor +addVertex2(Tag tag, Component0 &&c0, Component1 &&c1, Component2 &&c2, Component3 &&c3, ValueT &&val, + RenderGraph &g, RenderGraph::vertex_descriptor u = RenderGraph::null_vertex()) { + auto v = addVertex( + tag, + std::forward(c0), + std::forward(c1), + std::forward(c2), + std::forward(c3), + std::forward(val), + g, + u); + g.sortedVertices.emplace_back(v); + CC_EXPECTS(g.sortedVertices.size() == num_vertices(g)); + return v; +} + inline LayoutGraphData::vertex_descriptor getSubpassOrPassID( RenderGraph::vertex_descriptor vertID, const RenderGraph &rg, const LayoutGraphData &lg) { @@ -53,7 +71,7 @@ addRenderPassVertex( pass.count = count; pass.quality = quality; - auto passID = addVertex( + auto passID = addVertex2( RasterPassTag{}, std::forward_as_tuple(passName), std::forward_as_tuple(passName), @@ -94,7 +112,7 @@ addRenderSubpassVertex( subpass.viewport.width = pass.width; subpass.viewport.height = pass.height; - auto subpassID = addVertex( + auto subpassID = addVertex2( RasterSubpassTag{}, std::forward_as_tuple(subpassName), std::forward_as_tuple(subpassName), diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp index 0d6236eb388..c117da01e20 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp @@ -416,7 +416,8 @@ RenderGraph::RenderGraph(const allocator_type& alloc) noexcept dispatches(alloc), clearViews(alloc), viewports(alloc), - index(alloc) {} + index(alloc), + sortedVertices(alloc) {} RenderGraph::RenderGraph(RenderGraph&& rhs, const allocator_type& alloc) : objects(std::move(rhs.objects), alloc), @@ -439,7 +440,8 @@ RenderGraph::RenderGraph(RenderGraph&& rhs, const allocator_type& alloc) dispatches(std::move(rhs.dispatches), alloc), clearViews(std::move(rhs.clearViews), alloc), viewports(std::move(rhs.viewports), alloc), - index(std::move(rhs.index), alloc) {} + index(std::move(rhs.index), alloc), + sortedVertices(std::move(rhs.sortedVertices), alloc) {} // ContinuousContainer void RenderGraph::reserve(vertices_size_type sz) { diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index d0f7e0aa9f7..c081a404255 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -1123,6 +1123,7 @@ struct RenderGraph { ccstd::pmr::vector viewports; // Members PmrUnorderedStringMap index; + ccstd::pmr::vector sortedVertices; }; } // namespace render From 36f6570a12733e6c16b14b85146cada9865318bd Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 5 Jul 2023 18:58:58 +0800 Subject: [PATCH 41/57] use depth first visit on sorted vertices --- native/cocos/renderer/pipeline/custom/NativeExecutor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index f0646960f14..1e3353ca615 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -2212,7 +2212,12 @@ void NativePipeline::executeRenderGraph(const RenderGraph& rg) { scratch}; RenderGraphVisitor visitor{{}, ctx}; - boost::depth_first_search(fg, visitor, get(colors, rg)); + auto colors = rg.colors(scratch); + for (const auto vertID : ctx.g.sortedVertices) { + if (holds(vertID, ctx.g) || holds(vertID, ctx.g)) { + boost::depth_first_visit(fg, vertID, visitor, get(colors, ctx.g)); + } + } } // collect statistics From 50c34d5537d1eaf8c1fd21a3b324d59547fe975a Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Fri, 7 Jul 2023 10:25:12 +0800 Subject: [PATCH 42/57] go through msaa on metal & vk (#148) --- cocos/render-scene/core/pass.ts | 17 +- cocos/rendering/custom/index.jsb.ts | 6 +- cocos/rendering/custom/index.ts | 6 +- cocos/rendering/custom/web-pipeline.ts | 3 + .../renderer/gfx-metal/MTLCommandBuffer.mm | 22 +- native/cocos/renderer/gfx-metal/MTLDevice.h | 2 + native/cocos/renderer/gfx-metal/MTLDevice.mm | 7 + .../cocos/renderer/gfx-metal/MTLGPUObjects.h | 1 + native/cocos/renderer/gfx-metal/MTLUtils.mm | 12 +- .../cocos/renderer/gfx-vulkan/VKCommands.cpp | 10 +- .../pipeline/custom/FGDispatcherTypes.h | 2 + .../pipeline/custom/FrameGraphDispatcher.cpp | 256 +++++++++++++----- .../pipeline/custom/NativeExecutor.cpp | 74 +++-- .../pipeline/custom/NativePipeline.cpp | 1 + .../pipeline/custom/NativeRenderGraph.cpp | 28 ++ .../pipeline/custom/NativeRenderGraphUtils.h | 12 +- .../pipeline/custom/RenderGraphTypes.h | 1 + .../renderer/pipeline/custom/test/test.h | 5 +- .../src/complicated_barrier_case.cpp | 13 +- .../src/simple_closed_barrier_test.cpp | 8 +- 20 files changed, 351 insertions(+), 135 deletions(-) diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 9e7b2565003..80569dc5b87 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -28,13 +28,15 @@ import { TextureBase } from '../../asset/assets/texture-base'; import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { getPhaseID } from '../../rendering/pass-phase'; import { murmurhash2_32_gc, errorID, assertID, cclegacy, warnID } from '../../core'; -import { BufferUsageBit, DynamicStateFlagBit, DynamicStateFlags, Feature, GetTypeSize, MemoryUsageBit, PrimitiveMode, Type, Color, +import { + BufferUsageBit, DynamicStateFlagBit, DynamicStateFlags, Feature, GetTypeSize, MemoryUsageBit, PrimitiveMode, Type, Color, BlendState, BlendTarget, Buffer, BufferInfo, BufferViewInfo, DepthStencilState, DescriptorSet, DescriptorSetInfo, DescriptorSetLayout, Device, RasterizerState, Sampler, Texture, Shader, PipelineLayout, deviceManager, UniformBlock, } from '../../gfx'; import { EffectAsset } from '../../asset/assets/effect-asset'; import { IProgramInfo, programLib } from './program-lib'; -import { MacroRecord, MaterialProperty, customizeType, getBindingFromHandle, getDefaultFromType, getStringFromType, +import { + MacroRecord, MaterialProperty, customizeType, getBindingFromHandle, getDefaultFromType, getStringFromType, getOffsetFromHandle, getTypeFromHandle, type2reader, type2writer, getCountFromHandle, type2validator, } from './pass-utils'; import { RenderPassStage, RenderPriority } from '../../rendering/define'; @@ -190,6 +192,7 @@ export class Pass { protected _stage: RenderPassStage = RenderPassStage.DEFAULT; protected _phase = getPhaseID('default'); protected _passID = 0xFFFFFFFF; + protected _subpassID = 0xFFFFFFFF; protected _phaseID = 0xFFFFFFFF; protected _primitive: PrimitiveMode = PrimitiveMode.TRIANGLE_LIST; protected _batchingScheme: BatchingSchemes = BatchingSchemes.NONE; @@ -576,11 +579,17 @@ export class Pass { const r = cclegacy.rendering; if (typeof info.phase === 'number') { this._passID = (info as Pass)._passID; + this._subpassID = (info as Pass)._subpassID; this._phaseID = (info as Pass)._phaseID; } else { this._passID = r.getPassID(info.pass); if (this._passID !== r.INVALID_ID) { - this._phaseID = r.getPhaseID(this._passID, info.phase); + if (info.subpass) { + this._subpassID = r.getSubpassID(this._passID, info.subpass); + this._phaseID = r.getPhaseID(this._subpassID, info.phase); + } else { + this._phaseID = r.getPhaseID(this._passID, info.phase); + } } } if (this._passID === r.INVALID_ID) { @@ -778,7 +787,7 @@ export class Pass { this._blocks = target._blocks; this._blocksInt = target._blocksInt; - this._dynamics = target._dynamics; + this._dynamics = target._dynamics; this._shader = target._shader; diff --git a/cocos/rendering/custom/index.jsb.ts b/cocos/rendering/custom/index.jsb.ts index ce9a0e531f6..e0631e8ea1e 100644 --- a/cocos/rendering/custom/index.jsb.ts +++ b/cocos/rendering/custom/index.jsb.ts @@ -92,11 +92,15 @@ export function getPassID (name: string | undefined): number { return _renderModule.getPassID(name); } +export function getSubpassID (passID: number, name: string): number { + return _renderModule.getSubpassID(passID, name); +} + export function getPhaseID (passID: number, name: string | number | undefined): number { if (name === undefined) { return _renderModule.getPhaseID(passID, 'default'); } - if (typeof(name) === 'number') { + if (typeof (name) === 'number') { return _renderModule.getPhaseID(passID, name.toString()); } return _renderModule.getPhaseID(passID, name); diff --git a/cocos/rendering/custom/index.ts b/cocos/rendering/custom/index.ts index 2a21ea3b31e..1da01f93a53 100644 --- a/cocos/rendering/custom/index.ts +++ b/cocos/rendering/custom/index.ts @@ -32,7 +32,7 @@ import { LayoutGraphData, loadLayoutGraphData } from './layout-graph'; import { BinaryInputArchive } from './binary-archive'; import { WebProgramLibrary } from './web-program-library'; import { Device } from '../../gfx'; -import { initializeLayoutGraphData, terminateLayoutGraphData, getCustomPassID, getCustomPhaseID } from './layout-graph-utils'; +import { initializeLayoutGraphData, terminateLayoutGraphData, getCustomPassID, getCustomPhaseID, getCustomSubpassID } from './layout-graph-utils'; import { ProgramLibrary } from './private'; import { PostProcessBuilder } from '../post-process/post-process-builder'; @@ -101,6 +101,10 @@ export function getPassID (name: string | undefined): number { return getCustomPassID(defaultLayoutGraph, name); } +export function getSubpassID (passID: number, name: string): number { + return getCustomSubpassID(defaultLayoutGraph, passID, name); +} + export function getPhaseID (passID: number, name: string | number | undefined): number { return getCustomPhaseID(defaultLayoutGraph, passID, name); } diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 84a90f1369f..5fee47004f1 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1313,6 +1313,7 @@ export class WebPipeline implements BasicPipeline { if (renderWindow.swapchain === null) { assert(renderWindow.framebuffer.colorTextures.length === 1 && renderWindow.framebuffer.colorTextures[0] !== null); + desc.sampleCount = renderWindow.framebuffer.colorTextures[0].info.samples; return this._resourceGraph.addVertex( ResourceGraphValue.Framebuffer, renderWindow.framebuffer, @@ -1674,6 +1675,7 @@ export class WebPipeline implements BasicPipeline { desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; + desc.sampleCount = SampleCount.ONE; desc.flags = ResourceFlags.COLOR_ATTACHMENT | ResourceFlags.SAMPLED; return this._resourceGraph.addVertex( @@ -1693,6 +1695,7 @@ export class WebPipeline implements BasicPipeline { desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; + desc.sampleCount = SampleCount.ONE; desc.flags = ResourceFlags.DEPTH_STENCIL_ATTACHMENT | ResourceFlags.SAMPLED; return this._resourceGraph.addVertex( ResourceGraphValue.Managed, diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm index 0779591c601..e46e3eb8deb 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm @@ -237,6 +237,17 @@ of this software and associated engine source code (the "Software"), a limited, if(color >= colorAttachments.size()) { continue; // depthStencil as output } + if (subpasses[i].resolves.size() > j) { + uint32_t resolve = subpasses[i].resolves[j]; + auto *resolveTex = static_cast(colorTextures[resolve]); + if (resolveTex->textureInfo().samples != SampleCount::ONE) + continue; + mtlRenderPassDescriptor.colorAttachments[color].resolveTexture = resolveTex->getMTLTexture(); + mtlRenderPassDescriptor.colorAttachments[color].resolveLevel = 0; + mtlRenderPassDescriptor.colorAttachments[color].resolveSlice = 0; + mtlRenderPassDescriptor.colorAttachments[color].resolveDepthPlane = 0; + mtlRenderPassDescriptor.colorAttachments[color].storeAction = MTLStoreActionMultisampleResolve; + } if (visited[color]) continue; auto *ccMtlTexture = static_cast(colorTextures[color]); @@ -255,17 +266,6 @@ of this software and associated engine source code (the "Software"), a limited, mtlRenderPassDescriptor.colorAttachments[color].storeAction = mu::isFramebufferFetchSupported() ? mu::toMTLStoreAction(colorAttachments[color].storeOp) : MTLStoreActionStore; visited[color] = true; _colorAppearedBefore.set(color); - if (subpasses[i].resolves.size() > j) { - uint32_t resolve = subpasses[i].resolves[j]; - auto *resolveTex = static_cast(colorTextures[resolve]); - if (resolveTex->textureInfo().samples == SampleCount::ONE) - continue; - mtlRenderPassDescriptor.colorAttachments[color].resolveTexture = resolveTex->getMTLTexture(); - mtlRenderPassDescriptor.colorAttachments[color].resolveLevel = 0; - mtlRenderPassDescriptor.colorAttachments[color].resolveSlice = 0; - mtlRenderPassDescriptor.colorAttachments[color].resolveDepthPlane = 0; - mtlRenderPassDescriptor.colorAttachments[color].storeAction = MTLStoreActionMultisampleResolve; - } } } updateDepthStencilState(ccMtlRenderPass->getCurrentSubpassIndex(), mtlRenderPassDescriptor); diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.h b/native/cocos/renderer/gfx-metal/MTLDevice.h index b76443f1bd6..01068a1c787 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.h +++ b/native/cocos/renderer/gfx-metal/MTLDevice.h @@ -88,6 +88,8 @@ class CCMTLDevice final : public Device { _swapchains.erase(iter); } } + + inline CCMTLGPUDeviceObject* gpuObject() { return _gpuDeviceObj; } protected: static CCMTLDevice *_instance; diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.mm b/native/cocos/renderer/gfx-metal/MTLDevice.mm index db0ceef627d..daf0a1c42ba 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.mm +++ b/native/cocos/renderer/gfx-metal/MTLDevice.mm @@ -138,6 +138,13 @@ of this software and associated engine source code (the "Software"), a limited, _features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = false; _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = false; _features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = true; + + const uint32_t samples[] = {2, 4, 8, 16, 32}; + for (auto sampleCount : samples) { + if ([mtlDevice supportsTextureSampleCount:sampleCount]) { + _gpuDeviceObj->supportSamples.emplace_back(sampleCount); + } + } QueueInfo queueInfo; queueInfo.type = QueueType::GRAPHICS; diff --git a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h index 63a772f2080..b508230d15b 100644 --- a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h +++ b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h @@ -326,6 +326,7 @@ struct CCMTLGPUCommandBufferObject { struct CCMTLGPUDeviceObject { CCMTLCommandBuffer* _transferCmdBuffer{nullptr}; + ccstd::vector supportSamples; }; struct CCMTLGPUQueryPool { diff --git a/native/cocos/renderer/gfx-metal/MTLUtils.mm b/native/cocos/renderer/gfx-metal/MTLUtils.mm index 18869415bba..605c895fef9 100644 --- a/native/cocos/renderer/gfx-metal/MTLUtils.mm +++ b/native/cocos/renderer/gfx-metal/MTLUtils.mm @@ -847,16 +847,14 @@ void main() { } NSUInteger mu::toMTLSampleCount(SampleCount count) { - //TODO_Zeqiang: query from device. + auto* device = CCMTLDevice::getInstance(); + const auto& supportSamples = device->gpuObject()->supportSamples; switch (count) { case SampleCount::ONE: return 1; - case SampleCount::MULTIPLE_PERFORMANCE: return 2; - case SampleCount::MULTIPLE_BALANCE: return 4; + case SampleCount::MULTIPLE_PERFORMANCE: return supportSamples.front(); + case SampleCount::MULTIPLE_BALANCE: return supportSamples[supportSamples.size() - 1]; case SampleCount::MULTIPLE_QUALITY: - return 8; - // case SampleCount::X16: return 16; - // case SampleCount::X32: return 32; - // case SampleCount::X64: return 64; + return supportSamples.back(); } } diff --git a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp index d9bb087abf1..e39045970b6 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp @@ -434,11 +434,12 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; for (uint32_t input : subpassInfo.inputs) { + bool appearsInOutput = std::find(subpassInfo.colors.begin(), subpassInfo.colors.end(), input) != subpassInfo.colors.end(); if (input == gpuRenderPass->colorAttachments.size()) { - VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + VkImageLayout layout = subpassInfo.depthStencil != INVALID_BINDING ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, input, layout, VK_IMAGE_ASPECT_DEPTH_BIT}); } else { - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkImageLayout layout = appearsInOutput ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, input, layout, VK_IMAGE_ASPECT_COLOR_BIT}); } } @@ -450,8 +451,9 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, color, layout, VK_IMAGE_ASPECT_COLOR_BIT}); sampleCount = std::max(sampleCount, attachment.samples); } - for (uint32_t resolve : subpassInfo.resolves) { - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + for (uint32_t resolveIn : subpassInfo.resolves) { + VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + auto resolve = resolveIn == gfx::INVALID_BINDING ? VK_ATTACHMENT_UNUSED : resolveIn; attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, resolve, layout, VK_IMAGE_ASPECT_COLOR_BIT}); } diff --git a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h index f89f2c4aa2c..23da362322b 100644 --- a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h +++ b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h @@ -115,6 +115,8 @@ struct FGRenderPassInfo { std::vector colorAccesses; LayoutAccess dsAccess; gfx::RenderPassInfo rpInfo; + std::vector orderedViews; + bool needResolve{false}; }; struct ResourceAccessGraph { diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index b7ab9d3ef86..fd6052386b3 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "FGDispatcherGraphs.h" #include "FGDispatcherTypes.h" @@ -93,12 +94,12 @@ void FrameGraphDispatcher::setParalellWeight(float paralellExecWeight) { const ResourceAccessNode &FrameGraphDispatcher::getAttachmentStatus(RenderGraph::vertex_descriptor renderGraphVertID) const { auto iter = resourceAccessGraph.subpassIndex.find(renderGraphVertID); auto ragVertID = resourceAccessGraph.passIndex.at(renderGraphVertID); - const ResourceAccessNode* accessNode = &resourceAccessGraph.access.at(ragVertID); - if( iter != resourceAccessGraph.subpassIndex.end()) { + const ResourceAccessNode *accessNode = &resourceAccessGraph.access.at(ragVertID); + if (iter != resourceAccessGraph.subpassIndex.end()) { auto subpassIndex = iter->second; accessNode = accessNode->nextSubpass; CC_ASSERT(accessNode); - while(subpassIndex) { + while (subpassIndex) { accessNode = accessNode->nextSubpass; --subpassIndex; CC_ASSERT(accessNode); @@ -494,6 +495,9 @@ struct BarrierVisitor : public boost::bfs_visitor<> { dependency.srcSubpass = INVALID_ID; dependency.dstSubpass = subpassIdx; for (const auto &barrier : barriers.frontBarriers) { + if (barrier.beginStatus.accessFlag == gfx::AccessFlagBit::NONE) { + continue; + } auto resID = barrier.resourceID; auto findBarrierByResID = [resID](const Barrier &barrier) { return barrier.resourceID == resID; @@ -589,7 +593,6 @@ struct BarrierVisitor : public boost::bfs_visitor<> { if (dependency.prevAccesses != gfx::AccessFlagBit::NONE) { subpassDependencies.emplace_back(dependency); } - } ++subpassIdx; } @@ -1035,7 +1038,8 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { if (batchedBarriers.find(i) == batchedBarriers.end()) { batchedBarriers.emplace(i, BarrierNode{}); auto &rpInfo = rag.rpInfos[i].rpInfo; - if (rpInfo.subpasses.size() > 1) { + // NOLINTNEXTLINE (readability-container-size-empty) + if (rpInfo.subpasses.size() >= 1) { batchedBarriers[i].subpassBarriers.resize(rpInfo.subpasses.size()); } } @@ -1098,8 +1102,9 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { // external res barrier for next frame for (const auto &externalPair : externalResMap) { + const auto &resName = externalPair.first; const auto &transition = externalPair.second; - auto resID = resourceGraph.valueIndex.at(externalPair.first); + auto resID = resourceGraph.valueIndex.at(resName); const auto &resTraits = get(ResourceGraph::TraitsTag{}, resourceGraph, resID); auto &rescStates = get(ResourceGraph::StatesTag{}, resourceGraph, resID); @@ -1108,7 +1113,7 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { // 1. resource been written in this frame; // 2. first meet in this frame (no idea if any writes in next frame) // 3. backbuffer present - bool needNextBarrier = (namesSet.find(externalPair.first) != namesSet.end()) || (rescStates.states == gfx::AccessFlagBit::NONE); + bool needNextBarrier = (namesSet.find(resName) != namesSet.end()) || (rescStates.states == gfx::AccessFlagBit::NONE); // persistant resource states cached here rescStates.states = transition.currStatus.accessFlag; @@ -1145,21 +1150,13 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { bool hasSubpass = !(batchedBarriers[passID].subpassBarriers.size() <= 1); if (hasSubpass) { - auto &subpassBarriers = batchedBarriers[passID].subpassBarriers; - for (int i = static_cast(subpassBarriers.size()) - 1; i >= 0; --i) { - auto findBarrierByResID = [resID](const Barrier &barrier) { - return barrier.resourceID == resID; - }; - - const auto &frontBarriers = subpassBarriers[i].frontBarriers; - auto &rearBarriers = subpassBarriers[i].rearBarriers; - auto found = std::find_if(frontBarriers.begin(), frontBarriers.end(), findBarrierByResID) != frontBarriers.end() || - std::find_if(rearBarriers.begin(), rearBarriers.end(), findBarrierByResID) != rearBarriers.end(); - if (found) { - rearBarriers.push_back(nextFrameResBarrier); - break; - } - } + // rpinfo instead + auto &fgRenderPassInfo = rag.rpInfos.at(passID); + auto iter = std::find(fgRenderPassInfo.orderedViews.begin(), fgRenderPassInfo.orderedViews.end(), resName); + CC_ASSERT(iter != fgRenderPassInfo.orderedViews.end()); + auto index = std::distance(fgRenderPassInfo.orderedViews.begin(), iter); + index -= fgRenderPassInfo.rpInfo.depthStencilAttachment.format != gfx::Format::UNKNOWN; + fgRenderPassInfo.colorAccesses[index].nextAccess = nextFrameResBarrier.endStatus.accessFlag; } else { auto &rearBarriers = batchedBarriers[passID].blockBarrier.rearBarriers; rearBarriers.emplace_back(nextFrameResBarrier); @@ -1197,13 +1194,13 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { constexpr static bool USING_RENDERPASS_DEP_INSTEAD_OF_BARRIER{true}; if constexpr (USING_RENDERPASS_DEP_INSTEAD_OF_BARRIER) { - auto prune = [&rag, &renderGraph, &resourceGraph](std::vector& barriers) { + auto prune = [&rag, &renderGraph, &resourceGraph](std::vector &barriers) { barriers.erase(std::remove_if(barriers.begin(), barriers.end(), [&rag, &renderGraph, &resourceGraph](Barrier &barrier) { bool fromAttachment = isAttachmentAccess(barrier.beginStatus.accessFlag) || barrier.beginStatus.accessFlag == gfx::AccessFlagBit::NONE; bool toAttachment = isAttachmentAccess(barrier.endStatus.accessFlag); return toAttachment; - }), - barriers.end()); + }), + barriers.end()); }; for (auto &passBarrierInfo : batchedBarriers) { auto &passBarrierNode = passBarrierInfo.second; @@ -1860,22 +1857,23 @@ auto getResourceStatus(PassType passType, const PmrString &name, gfx::MemoryAcce // can't find this resource in layoutdata, not in descriptor so either input or output attachment. gfx::TextureUsage texUsage = gfx::TextureUsage::NONE; - // TODO(Zeqiang): visbility of slot name "_" not found - if (memAccess == gfx::MemoryAccess::READ_ONLY) { + if (hasFlag(memAccess, gfx::MemoryAccess::READ_ONLY)) { if ((desc.flags & ResourceFlags::INPUT_ATTACHMENT) != ResourceFlags::NONE && rasterized) { texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::INPUT_ATTACHMENT)); } else { texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::SAMPLED | gfx::TextureUsage::STORAGE | gfx::TextureUsage::SHADING_RATE | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT)); } - } else { + } + + if (hasFlag(memAccess, gfx::MemoryAccess::WRITE_ONLY)) { texUsage |= (mapTextureFlags(desc.flags) & (gfx::TextureUsage::COLOR_ATTACHMENT | gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT | gfx::TextureUsage::STORAGE)); } if (vis == gfx::ShaderStageFlags::NONE) { vis = passType == gfx::PassType::RASTER ? gfx::ShaderStageFlags::FRAGMENT : gfx::ShaderStageFlags::COMPUTE; } - + usage = texUsage; accesFlag = gfx::getAccessFlags(texUsage, memAccess, vis); } @@ -2094,23 +2092,63 @@ bool checkComputeViews(const Graphs &graphs, uint32_t vertID, uint32_t passID, P return dependent; } -void fillRenderPassInfo(const RasterView &view, gfx::RenderPassInfo &rpInfo, uint32_t index, const ResourceDesc &viewDesc) { - if (view.attachmentType != AttachmentType::DEPTH_STENCIL) { +bool checkResolveResource(const Graphs &graphs, uint32_t vertID, uint32_t /*passID*/, ResourceAccessNode &node, const ccstd::pmr::vector &resolves) { + const auto &[renderGraph, resourceGraph, layoutGraphData, resourceAccessGraph, relationGraph] = graphs; + bool dependent = false; + for (const auto &pair : resolves) { + const auto &resolveTargetName = pair.target; + const auto &desc = get(ResourceGraph::DescTag{}, resourceGraph, vertex(resolveTargetName, resourceGraph)); + gfx::AccessFlags accessFlag = gfx::AccessFlags::COLOR_ATTACHMENT_WRITE; + gfx::TextureUsage usage = gfx::TextureUsage::COLOR_ATTACHMENT; + if (desc.format == gfx::Format::DEPTH_STENCIL) { + accessFlag = gfx::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE; + usage = gfx::TextureUsage::DEPTH_STENCIL_ATTACHMENT; + } + ViewStatus viewStatus{resolveTargetName, + PassType::RASTER, + gfx::ShaderStageFlags::FRAGMENT, + gfx::MemoryAccess::WRITE_ONLY, + accessFlag, usage}; + addAccessStatus(resourceAccessGraph, resourceGraph, node, viewStatus); + auto lastVertId = dependencyCheck(resourceAccessGraph, vertID, resourceGraph, viewStatus); + if (lastVertId != INVALID_ID) { + tryAddEdge(lastVertId, vertID, resourceAccessGraph); + tryAddEdge(lastVertId, vertID, relationGraph); + dependent = true; + } + } + // sort for vector intersection + std::sort(node.attachmentStatus.begin(), node.attachmentStatus.end(), [](const AccessStatus &lhs, const AccessStatus &rhs) { return lhs.vertID < rhs.vertID; }); + + return dependent; +} + +void fillRenderPassInfo(gfx::LoadOp loadOp, gfx::StoreOp storeOp, AttachmentType attachmentType, gfx::RenderPassInfo &rpInfo, uint32_t index, const ResourceDesc &viewDesc, bool resolve) { + if (attachmentType != AttachmentType::DEPTH_STENCIL || resolve) { auto &colorAttachment = rpInfo.colorAttachments[index]; - colorAttachment.format = viewDesc.format; - colorAttachment.loadOp = view.loadOp; - colorAttachment.storeOp = view.storeOp; - colorAttachment.sampleCount = viewDesc.sampleCount; - // colorAttachment.barrier = getGeneralBarrier(gfx::Device::getInstance(), view, prevAccess, nextAccess); + if (colorAttachment.format == gfx::Format::UNKNOWN) { + colorAttachment.format = viewDesc.format; + colorAttachment.loadOp = loadOp; + colorAttachment.storeOp = storeOp; + colorAttachment.sampleCount = viewDesc.sampleCount; + } else { + colorAttachment.storeOp = storeOp; + } + } else { auto &depthStencilAttachment = rpInfo.depthStencilAttachment; - depthStencilAttachment.format = viewDesc.format; - depthStencilAttachment.depthLoadOp = view.loadOp; - depthStencilAttachment.depthStoreOp = view.storeOp; - depthStencilAttachment.stencilLoadOp = view.loadOp; - depthStencilAttachment.stencilStoreOp = view.storeOp; - depthStencilAttachment.sampleCount = viewDesc.sampleCount; - // depthStencilAttachment.barrier = getGeneralBarrier(gfx::Device::getInstance(), view, prevAccess, nextAccess); + if (depthStencilAttachment.format == gfx::Format::UNKNOWN) { + depthStencilAttachment.format = viewDesc.format; + depthStencilAttachment.depthLoadOp = loadOp; + depthStencilAttachment.depthStoreOp = storeOp; + depthStencilAttachment.stencilLoadOp = loadOp; + depthStencilAttachment.stencilStoreOp = storeOp; + depthStencilAttachment.sampleCount = viewDesc.sampleCount; + } else { + // TODO(Zeqiang): separate ds + depthStencilAttachment.depthStoreOp = storeOp; + depthStencilAttachment.stencilStoreOp = storeOp; + } } } @@ -2155,7 +2193,6 @@ void processRasterPass(const Graphs &graphs, uint32_t passID, const RasterPass & const auto &view = pass.rasterViews.at(name); const auto &viewDesc = get(ResourceGraph::DescTag{}, resourceGraph, resID); auto prevAccess = pair.second; - CC_ASSERT(slotID < node.attachmentStatus.size()); // TD:remove find auto nodeIter = std::find_if(node.attachmentStatus.begin(), node.attachmentStatus.end(), [resID](const AccessStatus &status) { return status.vertID == resID; @@ -2184,10 +2221,21 @@ void processRasterPass(const Graphs &graphs, uint32_t passID, const RasterPass & fgRenderpassInfo.dsAccess.prevAccess = prevAccess; fgRenderpassInfo.dsAccess.nextAccess = nextAccess; } - fillRenderPassInfo(view, rpInfo, slotID, viewDesc); + fillRenderPassInfo(view.loadOp, view.storeOp, view.attachmentType, rpInfo, slotID, viewDesc, false); + fgRenderpassInfo.orderedViews.emplace_back(name); } } else { - auto colorSize = pass.attachmentIndexMap.size(); + auto colorSize = pass.rasterViews.size(); + bool hasDS = std::any_of(pass.rasterViews.begin(), pass.rasterViews.end(), [](const auto &pair) { + return pair.second.attachmentType == AttachmentType::DEPTH_STENCIL; + }); + colorSize -= hasDS; + const auto &subpasses = pass.subpassGraph.subpasses; + uint32_t count = 0; + auto resolveNum = std::accumulate(subpasses.begin(), subpasses.end(), 0, [](uint32_t initVal, const Subpass &subpass) { + return initVal + subpass.resolvePairs.size(); + }); + colorSize += resolveNum; rpInfo.colorAttachments.resize(colorSize); fgRenderpassInfo.colorAccesses.resize(colorSize); } @@ -2208,7 +2256,7 @@ void processComputePass(const Graphs &graphs, uint32_t passID, const ComputePass } } -uint32_t record(const ccstd::vector& indices) { +uint32_t record(const ccstd::vector &indices) { uint32_t res = 0; for (auto attachmentIndex : indices) { res |= 1 << attachmentIndex; @@ -2216,7 +2264,7 @@ uint32_t record(const ccstd::vector& indices) { return res; } -void extract(uint32_t val, ccstd::vector& preserves) { +void extract(uint32_t val, ccstd::vector &preserves) { uint32_t index = 0; while (val) { if (val & 0x1) { @@ -2227,9 +2275,9 @@ void extract(uint32_t val, ccstd::vector& preserves) { } } -void getPreserves(gfx::RenderPassInfo& rpInfo) { - std::stack stack; - for (auto& info : rpInfo.subpasses) { +void getPreserves(gfx::RenderPassInfo &rpInfo) { + std::stack stack; + for (auto &info : rpInfo.subpasses) { stack.push(&info); } @@ -2268,6 +2316,7 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub uint32_t accessType; uint32_t attachmentType; std::string_view slotName; + uint32_t samplesReverseWeight; }; using RasterViewSortKey = std::tuple; struct SubpassRasterViewData { @@ -2276,16 +2325,35 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub gfx::AccessFlags access; }; + bool hasDS{false}; ccstd::vector viewIndex; for (const auto &[name, view] : pass.rasterViews) { auto resIter = rag.resourceIndex.find(name); + const auto &resID = vertex(name, resourceGraph); + const auto &desc = get(ResourceGraph::DescTag{}, resg, resID); gfx::AccessFlags prevAccess = resIter == rag.resourceIndex.end() ? gfx::AccessFlags::NONE : rag.accessRecord.at(resIter->second).currStatus.accessFlag; - viewIndex.emplace_back(SubpassRasterViewData { - {ACCESS_TYPE_WEIGHT[static_cast(view.accessType)], ATTACHMENT_TYPE_WEIGHT[static_cast(view.attachmentType)], view.slotName}, name, prevAccess + viewIndex.emplace_back(SubpassRasterViewData{ + {ACCESS_TYPE_WEIGHT[static_cast(view.accessType)], ATTACHMENT_TYPE_WEIGHT[static_cast(view.attachmentType)], view.slotName, static_cast(desc.sampleCount)}, + name, + prevAccess, + }); + hasDS |= view.attachmentType == AttachmentType::DEPTH_STENCIL; + } + + for (const auto &resolve : pass.resolvePairs) { + auto resIter = rag.resourceIndex.find(resolve.target); + gfx::AccessFlags prevAccess = resIter == rag.resourceIndex.end() ? gfx::AccessFlags::NONE : rag.accessRecord.at(resIter->second).currStatus.accessFlag; + viewIndex.emplace_back(SubpassRasterViewData{ + {ACCESS_TYPE_WEIGHT[static_cast(AccessType::WRITE)], ATTACHMENT_TYPE_WEIGHT[static_cast(AttachmentType::RENDER_TARGET)], "_", 0xFFFFFFFF}, + resolve.target, + prevAccess, }); } std::sort(viewIndex.begin(), viewIndex.end(), [](const SubpassRasterViewData &lhs, const SubpassRasterViewData &rhs) { + if (lhs.sortKey.samplesReverseWeight != rhs.sortKey.samplesReverseWeight) { + return lhs.sortKey.samplesReverseWeight < rhs.sortKey.samplesReverseWeight; + } if (lhs.sortKey.accessType != rhs.sortKey.accessType) { return lhs.sortKey.accessType < rhs.sortKey.accessType; } @@ -2311,50 +2379,94 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub bool dependent{false}; dependent |= checkRasterViews(graphs, parentRagVert, passID, PassType::RASTER, *head, pass.rasterViews); dependent |= checkComputeViews(graphs, parentRagVert, passID, PassType::RASTER, *head, pass.computeViews); + dependent |= checkResolveResource(graphs, parentRagVert, passID, *head, pass.resolvePairs); if (!dependent) { tryAddEdge(EXPECT_START_ID, parentRagVert, resourceAccessGraph); tryAddEdge(EXPECT_START_ID, parentRagVert, relationGraph); } + if (!pass.resolvePairs.empty()) { + // ds resolve stores in depthStencilResolve + subpassInfo.resolves.resize(pass.rasterViews.size() - hasDS, gfx::INVALID_BINDING); + } + uint32_t localSlot = 0; + bool dsAppeared{false}; for (const auto &[sortKey, name, access] : viewIndex) { const auto *const resName = name.data(); auto findByResID = [&](const AccessStatus &status) { return status.vertID == rag.resourceIndex.at(resName); }; auto iter = std::find_if(node.attachmentStatus.begin(), node.attachmentStatus.end(), findByResID); - const auto &view = pass.rasterViews.at(resName); + + // TODO(Zeqiang): remove find + const auto &targetName = name; auto resID = rag.resourceIndex.at(resName); const auto &viewDesc = get(ResourceGraph::DescTag{}, resg, rag.resourceIndex.at(resName)); - uint32_t slot = uberPass.attachmentIndexMap.size(); - if (view.attachmentType != AttachmentType::DEPTH_STENCIL) { + AttachmentType attachmentType{AttachmentType::RENDER_TARGET}; + AccessType accessType{AccessType::WRITE}; + gfx::LoadOp loadOp{gfx::LoadOp::DISCARD}; + gfx::StoreOp storeOp{gfx::StoreOp::STORE}; + + uint32_t slot = dsAppeared ? localSlot - 1 : localSlot; + // std::distance(uberPass.rasterViews.begin(), uberPass.rasterViews.find(resName)); + // slot = dsAppeared ? slot - 1 : slot; + /*if (attachmentType != AttachmentType::DEPTH_STENCIL) { CC_ASSERT(uberPass.attachmentIndexMap.count(resName)); slot = uberPass.attachmentIndexMap.at(resName); - } - + }*/ // TD:remove find auto nodeIter = std::find_if(head->attachmentStatus.begin(), head->attachmentStatus.end(), [resID](const AccessStatus &status) { return status.vertID == resID; }); auto nextAccess = nodeIter->accessFlag; - if (view.attachmentType != AttachmentType::DEPTH_STENCIL) { - if (view.attachmentType == AttachmentType::SHADING_RATE) { - subpassInfo.shadingRate = slot; + + auto resolveIter = std::find_if(pass.resolvePairs.begin(), pass.resolvePairs.end(), [&targetName](const ResolvePair &resolve) { + return strcmp(resolve.target.c_str(), targetName.data()) == 0; + }); + bool resolveView = resolveIter != pass.resolvePairs.end(); + if (resolveView) { + attachmentType = viewDesc.format == gfx::Format::DEPTH_STENCIL ? AttachmentType::DEPTH_STENCIL : AttachmentType::RENDER_TARGET; + if (attachmentType == AttachmentType::DEPTH_STENCIL) { + subpassInfo.depthStencilResolve = slot; + subpassInfo.depthResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode; + subpassInfo.stencilResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode1; } else { - if (view.accessType != AccessType::READ) { - subpassInfo.colors.emplace_back(slot); - } - if (view.accessType != AccessType::WRITE) { - subpassInfo.inputs.emplace_back(slot); - } + auto indexIter = std::find(fgRenderpassInfo.orderedViews.begin(), fgRenderpassInfo.orderedViews.end(), resolveIter->source); + auto srcIndex = indexIter == fgRenderpassInfo.orderedViews.end() ? fgRenderpassInfo.orderedViews.size() + : std::distance(fgRenderpassInfo.orderedViews.begin(), indexIter); + subpassInfo.resolves[srcIndex] = slot; } + accessType = AccessType::WRITE; + fgRenderpassInfo.colorAccesses[slot].nextAccess = nextAccess; } else { - fgRenderpassInfo.dsAccess.nextAccess = nextAccess; - subpassInfo.depthStencil = rpInfo.colorAttachments.size(); + const auto &view = pass.rasterViews.at(resName); + attachmentType = view.attachmentType; + accessType = view.accessType; + loadOp = view.loadOp; + storeOp = view.storeOp; + + if (attachmentType != AttachmentType::DEPTH_STENCIL) { + if (attachmentType == AttachmentType::SHADING_RATE) { + subpassInfo.shadingRate = slot; + } else { + if (accessType != AccessType::READ) { + subpassInfo.colors.emplace_back(slot); + } + if (accessType != AccessType::WRITE) { + subpassInfo.inputs.emplace_back(slot); + } + } + fgRenderpassInfo.colorAccesses[slot].nextAccess = nextAccess; + } else { + fgRenderpassInfo.dsAccess.nextAccess = nextAccess; + subpassInfo.depthStencil = rpInfo.colorAttachments.size(); + dsAppeared = true; + } } if (iter == node.attachmentStatus.end()) { @@ -2364,13 +2476,15 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub CC_ASSERT(head->attachmentStatus.size() > localSlot); auto nextAccess = head->attachmentStatus[localSlot].accessFlag; - if (view.attachmentType == AttachmentType::DEPTH_STENCIL) { + if (attachmentType == AttachmentType::DEPTH_STENCIL) { fgRenderpassInfo.dsAccess.prevAccess = prevAccess; } else { fgRenderpassInfo.colorAccesses[slot].prevAccess = prevAccess; } - fillRenderPassInfo(view, rpInfo, slot, viewDesc); + fgRenderpassInfo.orderedViews.emplace_back(resName); } + fillRenderPassInfo(loadOp, storeOp, attachmentType, rpInfo, slot, viewDesc, resolveView); + fgRenderpassInfo.needResolve |= resolveView; ++localSlot; } diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 1e3353ca615..c69906e668a 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -177,25 +177,31 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( fbInfo.colorTextures.reserve(pass.rasterViews.size()); PmrFlatSet set(scratch); - auto fillFrameBufferInfo = [&](const auto& pass) { - auto numTotalAttachments = static_cast(pass.rasterViews.size()); - - PmrFlatMap viewIndex(scratch); - for (const auto& [name, view] : pass.rasterViews) { - if (set.emplace(name).second) { - viewIndex.emplace(view.slotID, name); - } - } + auto fillFrameBufferInfo = [&](const ccstd::vector& passViews, bool hasResolve) { + const auto& uberPass = pass; + auto numTotalAttachments = static_cast(passViews.size()); // uint32_t dsvCount = 0; uint32_t index = 0; - for (const auto& [slotID, name] : viewIndex) { - const auto& view = pass.rasterViews.at(name); - const auto resID = vertex(name, ctx.resourceGraph); - const auto& desc = get(ResourceGraph::DescTag{}, ctx.resourceGraph, resID); + for (const auto& name : passViews) { + bool colorLikeView{true}; + bool dsAttachment{false}; + auto clearColor = gfx::Color{}; + auto iter = pass.rasterViews.find(name); + if(iter != pass.rasterViews.end()) { + const auto& view = iter->second; + colorLikeView = view.attachmentType == AttachmentType::RENDER_TARGET || view.attachmentType == AttachmentType::SHADING_RATE; + dsAttachment = !colorLikeView; + clearColor = view.clearColor; + } else { + // resolves + const auto resID = vertex(name, ctx.resourceGraph); + const auto& desc = get(ResourceGraph::DescTag{}, ctx.resourceGraph, resID); + CC_ASSERT(hasResolve && desc.sampleCount == gfx::SampleCount::ONE); + } - if (view.attachmentType == AttachmentType::RENDER_TARGET || view.attachmentType == AttachmentType::SHADING_RATE) { // RenderTarget - data.clearColors.emplace_back(view.clearColor); + if (colorLikeView) { // RenderTarget + data.clearColors.emplace_back(clearColor); auto resID = findVertex(name, resg); visitObject( @@ -239,9 +245,9 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( std::ignore = view; CC_EXPECTS(false); }); - } else if (view.attachmentType == AttachmentType::DEPTH_STENCIL) { // DepthStencil - data.clearDepth = view.clearColor.x; - data.clearStencil = static_cast(view.clearColor.y); + } else if (dsAttachment) { // DepthStencil + data.clearDepth = clearColor.x; + data.clearStencil = static_cast(clearColor.y); if (!fbInfo.depthStencilTexture) { auto resID = findVertex(name, resg); @@ -281,14 +287,14 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( // persistent cache data.clearColors.reserve(numColors); - rpInfo = ctx.fgd.resourceAccessGraph.rpInfos.at(ragVertID).rpInfo; - fillFrameBufferInfo(pass); + const auto& fgdRpInfo = ctx.fgd.resourceAccessGraph.rpInfos.at(ragVertID); + rpInfo = fgdRpInfo.rpInfo; + fillFrameBufferInfo(fgdRpInfo.orderedViews, false); } else { - rpInfo = ctx.fgd.resourceAccessGraph.rpInfos.at(ragVertID).rpInfo; - for (const auto& subpass : pass.subpassGraph.subpasses) { - fillFrameBufferInfo(subpass); - } + const auto& fgdRpInfo = ctx.fgd.resourceAccessGraph.rpInfos.at(ragVertID); + rpInfo = fgdRpInfo.rpInfo; + fillFrameBufferInfo(fgdRpInfo.orderedViews, fgdRpInfo.needResolve); } CC_ENSURES(rpInfo.colorAttachments.size() == data.clearColors.size()); CC_ENSURES(rpInfo.colorAttachments.size() == fbInfo.colorTextures.size()); @@ -923,6 +929,9 @@ getComputeViews(RenderGraph::vertex_descriptor passID, const RenderGraph& rg) { if (holds(passID, rg)) { return get(RasterPassTag{}, passID, rg).computeViews; } + if (holds(passID, rg)) { + return get(RasterSubpassTag{}, passID, rg).computeViews; + } CC_EXPECTS(holds(passID, rg)); return get(ComputeTag{}, passID, rg).computeViews; } @@ -1135,7 +1144,17 @@ struct RenderGraphUploadVisitor : boost::dfs_visitor<> { const auto& subpass = get(RasterSubpassTag{}, vertID, ctx.g); // render pass const auto& layoutName = get(RenderGraph::LayoutTag{}, ctx.g, vertID); - const auto& layoutID = locate(LayoutGraphData::null_vertex(), layoutName, ctx.lg); + + auto parentLayoutID = ctx.currentPassLayoutID; + auto layoutID = parentLayoutID; + if (!layoutName.empty()) { + auto parentID = parent(ctx.currentPassLayoutID, ctx.lg); + if (parentID != LayoutGraphData::null_vertex()) { + parentLayoutID = parentID; + } + layoutID = locate(parentLayoutID, layoutName, ctx.lg); + } + ctx.currentPassLayoutID = layoutID; // get layout auto& layout = get(LayoutGraphData::LayoutTag{}, ctx.lg, layoutID); @@ -1741,6 +1760,11 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { CC_EXPECTS(resID != ResourceGraph::null_vertex()); resg.mount(ctx.device, resID); } + for (const auto& resolve : pass.resolvePairs) { + auto resID = findVertex(resolve.target, resg); + CC_EXPECTS(resID != ResourceGraph::null_vertex()); + resg.mount(ctx.device, resID); + } } void mountResources(const RasterPass& pass) const { diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index c52b7276a3e..ff71720c937 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -101,6 +101,7 @@ uint32_t NativePipeline::addRenderWindow(const ccstd::string &name, gfx::Format if (!renderWindow->getSwapchain()) { CC_ASSERT(renderWindow->getFramebuffer()->getColorTextures().size() == 1); CC_ASSERT(renderWindow->getFramebuffer()->getColorTextures().at(0)); + desc.sampleCount = renderWindow->getFramebuffer()->getColorTextures().at(0)->getInfo().samples; return addVertex( FramebufferTag{}, std::forward_as_tuple(name.c_str()), diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index 28fa3ed130e..ccc608966be 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -319,6 +319,8 @@ void addRasterViewImpl( gfx::ShaderStageFlagBit::NONE)); CC_ENSURES(res.second); res.first->second.slotID = slotID; + + pass.rasterViews.emplace(name, subpass.rasterViews.at(name.data())); } CC_ENSURES(subpass.rasterViews.size() == subpassData.rasterViews.size()); } @@ -520,12 +522,19 @@ void NativeRenderSubpassBuilderImpl::setShowStatistics(bool enable) { void NativeMultisampleRenderSubpassBuilder::resolveRenderTarget( const ccstd::string &source, const ccstd::string &target) { // NOLINT(bugprone-easily-swappable-parameters) auto &subpass = get(RasterSubpassTag{}, nodeID, *renderGraph); + + auto parentID = parent(nodeID, *renderGraph); + auto &pass = get(RasterPassTag{}, parentID, *renderGraph); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + subpass.resolvePairs.emplace_back( ccstd::pmr::string(source.data(), renderGraph->get_allocator()), ccstd::pmr::string(target.data(), renderGraph->get_allocator()), ResolveFlags::COLOR, gfx::ResolveMode::AVERAGE, gfx::ResolveMode::NONE); + + subpassData.resolvePairs.emplace_back(subpass.resolvePairs.back()); } void NativeMultisampleRenderSubpassBuilder::resolveDepthStencil( @@ -539,12 +548,19 @@ void NativeMultisampleRenderSubpassBuilder::resolveDepthStencil( if (stencilMode != gfx::ResolveMode::NONE) { flags |= ResolveFlags::STENCIL; } + + auto parentID = parent(nodeID, *renderGraph); + auto &pass = get(RasterPassTag{}, parentID, *renderGraph); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + subpass.resolvePairs.emplace_back( ccstd::pmr::string(source.data(), renderGraph->get_allocator()), ccstd::pmr::string(target.data(), renderGraph->get_allocator()), flags, depthMode, stencilMode); + + subpassData.resolvePairs.emplace_back(subpass.resolvePairs.back()); } void NativeComputeSubpassBuilder::addRenderTarget(const ccstd::string &name, const ccstd::string &slotName) { @@ -1074,12 +1090,18 @@ void NativeMultisampleRenderPassBuilder::setShowStatistics(bool enable) { void NativeMultisampleRenderPassBuilder::resolveRenderTarget( const ccstd::string &source, const ccstd::string &target) { // NOLINT(bugprone-easily-swappable-parameters) auto &subpass = get(RasterSubpassTag{}, subpassID, *renderGraph); + + auto &pass = get(RasterPassTag{}, nodeID, *renderGraph); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + subpass.resolvePairs.emplace_back( ccstd::pmr::string(source.data(), renderGraph->get_allocator()), ccstd::pmr::string(target.data(), renderGraph->get_allocator()), ResolveFlags::COLOR, gfx::ResolveMode::AVERAGE, gfx::ResolveMode::NONE); + + subpassData.resolvePairs.emplace_back(subpass.resolvePairs.back()); } void NativeMultisampleRenderPassBuilder::resolveDepthStencil( @@ -1093,12 +1115,18 @@ void NativeMultisampleRenderPassBuilder::resolveDepthStencil( if (stencilMode != gfx::ResolveMode::NONE) { flags |= ResolveFlags::STENCIL; } + + auto &pass = get(RasterPassTag{}, nodeID, *renderGraph); + auto &subpassData = get(SubpassGraph::SubpassTag{}, pass.subpassGraph, subpass.subpassID); + subpass.resolvePairs.emplace_back( ccstd::pmr::string(source.data(), renderGraph->get_allocator()), ccstd::pmr::string(target.data(), renderGraph->get_allocator()), flags, depthMode, stencilMode); + + subpassData.resolvePairs.emplace_back(subpass.resolvePairs.back()); } // NativeComputeQueue diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h index 82541e18db0..18858869210 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraphUtils.h @@ -48,10 +48,14 @@ inline LayoutGraphData::vertex_descriptor getSubpassOrPassID( CC_ENSURES(passLayoutID != LayoutGraphData::null_vertex()); const auto &subpassLayoutName = get(RenderGraph::LayoutTag{}, rg, subpassOrPassID); - CC_ENSURES(!subpassLayoutName.empty()); - const auto subpassLayoutID = locate(passLayoutID, subpassLayoutName, lg); - CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex()); - layoutID = subpassLayoutID; + if (subpassLayoutName.empty()) { + layoutID = passLayoutID; // expect to be multisample pass + } else { + const auto subpassLayoutID = locate(passLayoutID, subpassLayoutName, lg); + CC_ENSURES(subpassLayoutID != LayoutGraphData::null_vertex()); + layoutID = subpassLayoutID; + } + } CC_ENSURES(layoutID != LayoutGraphData::null_vertex()); return layoutID; diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index c081a404255..14ef3c7c858 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -242,6 +242,7 @@ struct Subpass { PmrTransparentMap rasterViews; PmrTransparentMap> computeViews; + ccstd::pmr::vector resolvePairs; }; inline bool operator==(const Subpass& lhs, const Subpass& rhs) noexcept { diff --git a/native/cocos/renderer/pipeline/custom/test/test.h b/native/cocos/renderer/pipeline/custom/test/test.h index d5d2b5e0458..645e6d624f6 100644 --- a/native/cocos/renderer/pipeline/custom/test/test.h +++ b/native/cocos/renderer/pipeline/custom/test/test.h @@ -149,7 +149,7 @@ static void fillTestGraph(const ViewInfo &rasterData, const ResourceInfo &rescIn nameSet.emplace(viewName); } - auto &rasterViews = hasSubpass ? (*subpass).rasterViews : raster.rasterViews; + auto &views = hasSubpass ? (*subpass).rasterViews : raster.rasterViews; auto view = RasterView{ viewName.c_str(), isOutput ? AccessType::WRITE : AccessType::READ, @@ -161,7 +161,7 @@ static void fillTestGraph(const ViewInfo &rasterData, const ResourceInfo &rescIn gfx::ShaderStageFlagBit::NONE, }; view.slotID = slot; - rasterViews.emplace(viewName.c_str(), view); + views.emplace(viewName.c_str(), view); if (subpassViews) { subpassViews->emplace(viewName.c_str(), view); @@ -170,6 +170,7 @@ static void fillTestGraph(const ViewInfo &rasterData, const ResourceInfo &rescIn if (iter == raster.attachmentIndexMap.end()) { raster.attachmentIndexMap.emplace(viewName, newID); } + rasterViews.emplace(viewName, view); } ++slot; } diff --git a/native/tests/unit-test/src/complicated_barrier_case.cpp b/native/tests/unit-test/src/complicated_barrier_case.cpp index ec1f32703e2..3fdb5ae8a40 100644 --- a/native/tests/unit-test/src/complicated_barrier_case.cpp +++ b/native/tests/unit-test/src/complicated_barrier_case.cpp @@ -136,7 +136,11 @@ TEST(complicatedBarrierTest, test12) { const auto& node3 = barrierMap.at(3); ExpectEq(node3.blockBarrier.frontBarriers.empty(), true); ExpectEq(node3.blockBarrier.rearBarriers.empty(), true); - ExpectEq(node3.subpassBarriers.empty(), true); + + // subpass barrier size is the same as renderpass subpassinfo, though maybe empty. + ExpectEq(node3.subpassBarriers.size() == 1, true); + ExpectEq(node3.subpassBarriers.front().frontBarriers.empty(), true); + ExpectEq(node3.subpassBarriers.front().rearBarriers.empty(), true); //node4 const auto& node4 = barrierMap.at(4); @@ -181,6 +185,7 @@ TEST(complicatedBarrierTest, test12) { const auto& node5 = barrierMap.at(5); ExpectEq(node5.blockBarrier.frontBarriers.size() == 1, true); ExpectEq(node5.blockBarrier.rearBarriers.size() == 1, true); + // not raster pass ExpectEq(node5.subpassBarriers.empty(), true); auto iter7in5 = findBarrierByResID(node5.blockBarrier.rearBarriers, 7); @@ -198,6 +203,7 @@ TEST(complicatedBarrierTest, test12) { ExpectEq(node6.blockBarrier.frontBarriers.size() == 1, true); // resource later used by raster pass, so that layout can be transferred automatically. ExpectEq(node6.blockBarrier.rearBarriers.empty(), true); + // not a raster pass ExpectEq(node6.subpassBarriers.empty(), true); // node7 @@ -205,7 +211,7 @@ TEST(complicatedBarrierTest, test12) { // undefined layout already in initial layout ExpectEq(node7.blockBarrier.frontBarriers.empty(), true); ExpectEq(node7.blockBarrier.rearBarriers.empty(), true); - ExpectEq(node7.subpassBarriers.empty(), true); + ExpectEq(node7.subpassBarriers.empty(), false); ExpectEq(node7.blockBarrier.rearBarriers.size(), 0); @@ -219,7 +225,7 @@ TEST(complicatedBarrierTest, test12) { const auto& node13 = barrierMap.at(13); ExpectEq(node13.blockBarrier.frontBarriers.size(), 0); ExpectEq(node13.blockBarrier.rearBarriers.size(), 0); - ExpectEq(node13.subpassBarriers.empty(), true); + ExpectEq(node13.subpassBarriers.empty(), false); //node14: almost the same as 13 @@ -234,6 +240,7 @@ TEST(complicatedBarrierTest, test12) { const auto& node16 = barrierMap.at(16); ExpectEq(node16.blockBarrier.frontBarriers.empty(), true); ExpectEq(node16.blockBarrier.rearBarriers.empty(), true); + // not raster pass ExpectEq(node16.subpassBarriers.empty(), true); //runTestGraph(renderGraph, rescGraph, layoutGraphData, fgDispatcher); diff --git a/native/tests/unit-test/src/simple_closed_barrier_test.cpp b/native/tests/unit-test/src/simple_closed_barrier_test.cpp index 6cfbcc275e2..644132e90fb 100644 --- a/native/tests/unit-test/src/simple_closed_barrier_test.cpp +++ b/native/tests/unit-test/src/simple_closed_barrier_test.cpp @@ -54,7 +54,9 @@ TEST(simpleClosedBarrierTest, test11) { const auto& node1 = barrierMap.at(1); ExpectEq(node1.blockBarrier.frontBarriers.size(), 0); ExpectEq(node1.blockBarrier.rearBarriers.size(), 0); - ExpectEq(node1.subpassBarriers.empty(), true); + ExpectEq(node1.subpassBarriers.size() == 1, true); + ExpectEq(node1.subpassBarriers.front().frontBarriers.empty(), true); + ExpectEq(node1.subpassBarriers.front().rearBarriers.empty(), true); // transitioned by renderpass info //ExpectEq(node1.blockBarrier.rearBarriers[0].type == cc::gfx::BarrierType::FULL, true); @@ -65,7 +67,9 @@ TEST(simpleClosedBarrierTest, test11) { const auto& node2 = barrierMap.at(2); ExpectEq(node2.blockBarrier.frontBarriers.size(), 0); ExpectEq(node2.blockBarrier.rearBarriers.size(), 0); - ExpectEq(node2.subpassBarriers.empty(), true); + ExpectEq(node2.subpassBarriers.size() == 1, true); + ExpectEq(node2.subpassBarriers.front().frontBarriers.empty(), true); + ExpectEq(node2.subpassBarriers.front().rearBarriers.empty(), true); // ditto //// res3 From 242cc4e57d8608af146e9df2c8d45e1e807ad360 Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Fri, 7 Jul 2023 17:57:10 +0800 Subject: [PATCH 43/57] 3.8.0 msaa update (#149) --- .../pipeline/custom/FGDispatcherTypes.h | 2 +- .../pipeline/custom/FrameGraphDispatcher.cpp | 4 ++-- .../pipeline/custom/NativeExecutor.cpp | 5 ++-- .../pipeline/custom/RenderCommonFwd.h | 10 ++++++++ .../pipeline/custom/RenderCommonTypes.h | 24 +++++++++++++++++++ .../pipeline/custom/RenderGraphTypes.cpp | 9 ++++--- .../pipeline/custom/RenderGraphTypes.h | 5 ++-- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h index 23da362322b..91bf73662c2 100644 --- a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h +++ b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h @@ -115,7 +115,7 @@ struct FGRenderPassInfo { std::vector colorAccesses; LayoutAccess dsAccess; gfx::RenderPassInfo rpInfo; - std::vector orderedViews; + std::vector orderedViews; bool needResolve{false}; }; diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index fd6052386b3..cdd02a4f30c 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -1152,7 +1152,7 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { if (hasSubpass) { // rpinfo instead auto &fgRenderPassInfo = rag.rpInfos.at(passID); - auto iter = std::find(fgRenderPassInfo.orderedViews.begin(), fgRenderPassInfo.orderedViews.end(), resName); + auto iter = std::find(fgRenderPassInfo.orderedViews.begin(), fgRenderPassInfo.orderedViews.end(), resName.c_str()); CC_ASSERT(iter != fgRenderPassInfo.orderedViews.end()); auto index = std::distance(fgRenderPassInfo.orderedViews.begin(), iter); index -= fgRenderPassInfo.rpInfo.depthStencilAttachment.format != gfx::Format::UNKNOWN; @@ -2435,7 +2435,7 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub subpassInfo.depthResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode; subpassInfo.stencilResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode1; } else { - auto indexIter = std::find(fgRenderpassInfo.orderedViews.begin(), fgRenderpassInfo.orderedViews.end(), resolveIter->source); + auto indexIter = std::find(fgRenderpassInfo.orderedViews.begin(), fgRenderpassInfo.orderedViews.end(), resolveIter->source.c_str()); auto srcIndex = indexIter == fgRenderpassInfo.orderedViews.end() ? fgRenderpassInfo.orderedViews.size() : std::distance(fgRenderpassInfo.orderedViews.begin(), indexIter); subpassInfo.resolves[srcIndex] = slot; diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 5966ac4f083..bb71c6192c2 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -177,13 +177,14 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( fbInfo.colorTextures.reserve(pass.rasterViews.size()); PmrFlatSet set(scratch); - auto fillFrameBufferInfo = [&](const ccstd::vector& passViews, bool hasResolve) { + auto fillFrameBufferInfo = [&](const ccstd::vector& passViews, bool hasResolve) { const auto& uberPass = pass; auto numTotalAttachments = static_cast(passViews.size()); // uint32_t dsvCount = 0; uint32_t index = 0; - for (const auto& name : passViews) { + for (const auto nameIn : passViews) { + const char* name = nameIn.c_str(); bool colorLikeView{true}; bool dsAttachment{false}; auto clearColor = gfx::Color{}; diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h b/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h index 8f54ad52ca6..1628d725ef7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonFwd.h @@ -29,6 +29,7 @@ */ // clang-format off #pragma once +#include "cocos/base/std/hash/hash.h" #include "cocos/base/std/variant.h" #include "cocos/renderer/gfx-base/GFXDef-common.h" @@ -84,4 +85,13 @@ struct PipelineStatistics; } // namespace cc +namespace ccstd { + +template <> +struct hash { + hash_t operator()(const cc::render::ResolvePair& val) const noexcept; +}; + +} // namespace ccstd + // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index b0ff54e7d8c..56da2384bb5 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -32,6 +32,7 @@ #include "cocos/base/Ptr.h" #include "cocos/base/std/container/map.h" #include "cocos/base/std/container/string.h" +#include "cocos/base/std/hash/hash.h" #include "cocos/renderer/gfx-base/GFXDef-common.h" #include "cocos/renderer/pipeline/custom/RenderCommonFwd.h" #include "cocos/scene/Light.h" @@ -326,6 +327,15 @@ struct ResolvePair { gfx::ResolveMode mode1{gfx::ResolveMode::SAMPLE_ZERO}; }; +inline bool operator==(const ResolvePair& lhs, const ResolvePair& rhs) noexcept { + return std::forward_as_tuple(lhs.source, lhs.target, lhs.resolveFlags, lhs.mode, lhs.mode1) == + std::forward_as_tuple(rhs.source, rhs.target, rhs.resolveFlags, rhs.mode, rhs.mode1); +} + +inline bool operator!=(const ResolvePair& lhs, const ResolvePair& rhs) noexcept { + return !(lhs == rhs); +} + struct CopyPair { using allocator_type = boost::container::pmr::polymorphic_allocator; allocator_type get_allocator() const noexcept { // NOLINT @@ -421,4 +431,18 @@ struct PipelineStatistics { } // namespace cc +namespace ccstd { + +inline hash_t hash::operator()(const cc::render::ResolvePair& val) const noexcept { + hash_t seed = 0; + hash_combine(seed, val.source); + hash_combine(seed, val.target); + hash_combine(seed, val.resolveFlags); + hash_combine(seed, val.mode); + hash_combine(seed, val.mode1); + return seed; +} + +} // namespace ccstd + // clang-format on diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp index c117da01e20..bcb977b9e35 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.cpp @@ -124,15 +124,18 @@ ComputeView::ComputeView(ComputeView const& rhs, const allocator_type& alloc) Subpass::Subpass(const allocator_type& alloc) noexcept : rasterViews(alloc), - computeViews(alloc) {} + computeViews(alloc), + resolvePairs(alloc) {} Subpass::Subpass(Subpass&& rhs, const allocator_type& alloc) : rasterViews(std::move(rhs.rasterViews), alloc), - computeViews(std::move(rhs.computeViews), alloc) {} + computeViews(std::move(rhs.computeViews), alloc), + resolvePairs(std::move(rhs.resolvePairs), alloc) {} Subpass::Subpass(Subpass const& rhs, const allocator_type& alloc) : rasterViews(rhs.rasterViews, alloc), - computeViews(rhs.computeViews, alloc) {} + computeViews(rhs.computeViews, alloc), + resolvePairs(rhs.resolvePairs, alloc) {} SubpassGraph::SubpassGraph(const allocator_type& alloc) noexcept : _vertices(alloc), diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index 14ef3c7c858..ab3562cda73 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -246,8 +246,8 @@ struct Subpass { }; inline bool operator==(const Subpass& lhs, const Subpass& rhs) noexcept { - return std::forward_as_tuple(lhs.rasterViews, lhs.computeViews) == - std::forward_as_tuple(rhs.rasterViews, rhs.computeViews); + return std::forward_as_tuple(lhs.rasterViews, lhs.computeViews, lhs.resolvePairs) == + std::forward_as_tuple(rhs.rasterViews, rhs.computeViews, rhs.resolvePairs); } inline bool operator!=(const Subpass& lhs, const Subpass& rhs) noexcept { @@ -1170,6 +1170,7 @@ inline hash_t hash::operator()(const cc::render::Subpass& v hash_t seed = 0; hash_combine(seed, val.rasterViews); hash_combine(seed, val.computeViews); + hash_combine(seed, val.resolvePairs); return seed; } From 72041a9105fba803fbd7cfb6514a6cbe939e7f6f Mon Sep 17 00:00:00 2001 From: Zach Lee Date: Tue, 11 Jul 2023 10:51:14 +0800 Subject: [PATCH 44/57] gfx msaa && memoryless (#147) --- .../workflows/native-compile-platforms.yml | 17 +- .github/workflows/native-simulator.yml | 6 +- cocos/gfx/base/define.ts | 23 +- cocos/gfx/base/device.ts | 15 +- cocos/gfx/webgl/webgl-commands.ts | 48 +- cocos/gfx/webgl2/webgl2-commands.ts | 50 +- cocos/rendering/custom/executor.ts | 94 +- cocos/rendering/custom/render-graph.ts | 2 +- cocos/rendering/custom/types.ts | 2 + cocos/rendering/custom/web-pipeline.ts | 4 +- native/cocos/core/assets/RenderTexture.cpp | 2 +- .../cocos/renderer/frame-graph/FrameGraph.cpp | 2 +- .../renderer/gfx-agent/CommandBufferAgent.cpp | 21 + .../renderer/gfx-agent/CommandBufferAgent.h | 1 + .../cocos/renderer/gfx-agent/DeviceAgent.cpp | 4 + native/cocos/renderer/gfx-agent/DeviceAgent.h | 2 +- .../renderer/gfx-agent/FramebufferAgent.cpp | 3 + .../renderer/gfx-base/GFXCommandBuffer.h | 1 + .../cocos/renderer/gfx-base/GFXDef-common.h | 28 +- native/cocos/renderer/gfx-base/GFXDef.cpp | 24 +- native/cocos/renderer/gfx-base/GFXDevice.cpp | 2 +- native/cocos/renderer/gfx-base/GFXDevice.h | 8 +- .../renderer/gfx-base/GFXFramebuffer.cpp | 2 + .../cocos/renderer/gfx-base/GFXFramebuffer.h | 2 + .../cocos/renderer/gfx-base/GFXRenderPass.cpp | 5 +- .../cocos/renderer/gfx-base/GFXRenderPass.h | 2 + native/cocos/renderer/gfx-base/GFXTexture.cpp | 2 +- .../renderer/gfx-empty/EmptyCommandBuffer.cpp | 3 + .../renderer/gfx-empty/EmptyCommandBuffer.h | 1 + .../renderer/gfx-gles2/GLES2CommandBuffer.cpp | 4 + .../renderer/gfx-gles2/GLES2CommandBuffer.h | 1 + .../renderer/gfx-gles2/GLES2Commands.cpp | 29 +- .../cocos/renderer/gfx-gles2/GLES2Commands.h | 2 + .../cocos/renderer/gfx-gles2/GLES2Device.cpp | 8 + native/cocos/renderer/gfx-gles2/GLES2Device.h | 2 +- .../renderer/gfx-gles2/GLES2GPUObjects.h | 4 +- .../gfx-gles2/GLES2PrimaryCommandBuffer.cpp | 4 + .../gfx-gles2/GLES2PrimaryCommandBuffer.h | 1 + .../cocos/renderer/gfx-gles2/GLES2Texture.cpp | 10 +- .../renderer/gfx-gles3/GLES3CommandBuffer.cpp | 4 + .../renderer/gfx-gles3/GLES3CommandBuffer.h | 1 + .../renderer/gfx-gles3/GLES3Commands.cpp | 946 +++++++++--------- .../cocos/renderer/gfx-gles3/GLES3Commands.h | 2 + .../cocos/renderer/gfx-gles3/GLES3Device.cpp | 11 +- native/cocos/renderer/gfx-gles3/GLES3Device.h | 4 +- .../renderer/gfx-gles3/GLES3Framebuffer.cpp | 27 +- .../renderer/gfx-gles3/GLES3Framebuffer.h | 1 + .../renderer/gfx-gles3/GLES3GPUObjects.h | 86 +- .../gfx-gles3/GLES3PrimaryCommandBuffer.cpp | 4 + .../gfx-gles3/GLES3PrimaryCommandBuffer.h | 1 + .../renderer/gfx-gles3/GLES3RenderPass.cpp | 10 +- .../cocos/renderer/gfx-gles3/GLES3Texture.cpp | 10 +- .../renderer/gfx-metal/MTLCommandBuffer.h | 1 + .../renderer/gfx-metal/MTLCommandBuffer.mm | 16 +- native/cocos/renderer/gfx-metal/MTLDevice.h | 3 +- native/cocos/renderer/gfx-metal/MTLDevice.mm | 32 +- .../cocos/renderer/gfx-metal/MTLGPUObjects.h | 9 +- .../renderer/gfx-metal/MTLPipelineState.mm | 2 +- native/cocos/renderer/gfx-metal/MTLTexture.h | 2 + native/cocos/renderer/gfx-metal/MTLTexture.mm | 39 +- native/cocos/renderer/gfx-metal/MTLUtils.mm | 10 +- .../gfx-validator/CommandBufferValidator.cpp | 39 +- .../gfx-validator/CommandBufferValidator.h | 1 + .../gfx-validator/DeviceValidator.cpp | 4 + .../renderer/gfx-validator/DeviceValidator.h | 2 +- .../gfx-validator/FramebufferValidator.cpp | 11 + .../renderer/gfx-vulkan/VKCommandBuffer.cpp | 54 +- .../renderer/gfx-vulkan/VKCommandBuffer.h | 1 + .../cocos/renderer/gfx-vulkan/VKCommands.cpp | 199 ++-- native/cocos/renderer/gfx-vulkan/VKDevice.cpp | 19 + native/cocos/renderer/gfx-vulkan/VKDevice.h | 2 +- .../renderer/gfx-vulkan/VKFramebuffer.cpp | 5 + .../cocos/renderer/gfx-vulkan/VKGPUObjects.h | 17 +- .../renderer/gfx-vulkan/VKRenderPass.cpp | 10 +- .../cocos/renderer/gfx-vulkan/VKTexture.cpp | 6 +- native/cocos/renderer/gfx-vulkan/VKUtils.cpp | 24 +- native/cocos/renderer/gfx-vulkan/VKUtils.h | 3 +- .../gfx-wgpu/WGPUDescriptorSetLayout.cpp | 2 +- .../renderer/gfx-wgpu/WGPURenderPass.cpp | 8 +- .../cocos/renderer/gfx-wgpu/WGPUTexture.cpp | 4 +- native/cocos/renderer/gfx-wgpu/WGPUUtils.h | 16 +- .../pipeline/custom/FGDispatcherTypes.h | 1 + .../pipeline/custom/FrameGraphDispatcher.cpp | 35 +- .../pipeline/custom/NativeExecutor.cpp | 40 +- .../pipeline/custom/NativePipeline.cpp | 33 +- .../pipeline/custom/NativeResourceGraph.cpp | 11 +- .../pipeline/custom/RenderCommonTypes.h | 2 + .../pipeline/custom/RenderGraphTypes.h | 2 +- .../renderer/pipeline/custom/test/test.h | 46 +- .../renderer/pipeline/shadow/ShadowFlow.cpp | 4 +- native/tools/swig-config/gfx.i | 1 + 91 files changed, 1302 insertions(+), 962 deletions(-) diff --git a/.github/workflows/native-compile-platforms.yml b/.github/workflows/native-compile-platforms.yml index 5a8584b332e..7a8f43db48f 100644 --- a/.github/workflows/native-compile-platforms.yml +++ b/.github/workflows/native-compile-platforms.yml @@ -14,7 +14,7 @@ concurrency: jobs: compile_windows: name: "Windows" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: windows-2019 steps: @@ -24,9 +24,6 @@ jobs: run: | EXT_VERSION=`node ./.github/workflows/get-native-external-version.js` git clone --branch $EXT_VERSION --depth 1 https://github.com/cocos/cocos-engine-external native/external - - name: Install deps - run: | - choco install --forcex86 vulkan-sdk - name: Compile win64 shell: bash env: @@ -55,7 +52,7 @@ jobs: compile_android_minimal: name: "Android Minimal" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: ubuntu-latest steps: @@ -125,7 +122,7 @@ jobs: compile_android: name: "Android" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: ubuntu-latest steps: @@ -198,7 +195,7 @@ jobs: compile_mac_x86_64: name: "MacOS x86_64" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: macos-latest steps: @@ -247,7 +244,7 @@ jobs: compile_mac_arm64: name: "MacOS arm64" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: macos-latest steps: @@ -293,13 +290,13 @@ jobs: compile_iOS: name: "iOS" - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) runs-on: macos-11 steps: - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: 12.4 + xcode-version: 12.4 - uses: actions/checkout@v2 - name: Download external libraries shell: bash diff --git a/.github/workflows/native-simulator.yml b/.github/workflows/native-simulator.yml index 7465f448731..837ebdbcf81 100644 --- a/.github/workflows/native-simulator.yml +++ b/.github/workflows/native-simulator.yml @@ -14,7 +14,7 @@ concurrency: jobs: win_gen_simulator: runs-on: windows-2019 - if: + if: (! contains(github.event.pull_request.body, '[X] does not change any runtime related code or build configuration')) name: Windows defaults: @@ -31,10 +31,6 @@ jobs: run: | EXT_VERSION=`node ../.github/workflows/get-native-external-version.js` git clone --branch $EXT_VERSION --depth 1 https://github.com/cocos/cocos-engine-external external - - - name: install vulkan-sdk - run: | - choco install vulkan-sdk - name: gen simulator run: | gulp gen-simulator diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index c37926b064d..4543ff19c38 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -129,6 +129,7 @@ export enum Feature { SUBPASS_COLOR_INPUT, SUBPASS_DEPTH_STENCIL_INPUT, RASTERIZATION_ORDER_COHERENT, + MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL, COUNT, } @@ -405,6 +406,7 @@ export enum TextureFlagBit { GENERAL_LAYOUT = 0x2, // For inout framebuffer attachments EXTERNAL_OES = 0x4, // External oes texture EXTERNAL_NORMAL = 0x8, // External normal texture + LAZILY_ALLOCATED = 0x10 // Try lazily allocated mode. } export enum FormatFeatureBit { @@ -417,10 +419,13 @@ export enum FormatFeatureBit { } export enum SampleCount { - ONE, // Single sample - MULTIPLE_PERFORMANCE, // Multiple samples prioritizing performance over quality - MULTIPLE_BALANCE, // Multiple samples leveraging both quality and performance - MULTIPLE_QUALITY, // Multiple samples prioritizing quality over performance + X1 = 0x01, + X2 = 0x02, + X4 = 0x04, + X8 = 0x08, + X16 = 0x10, + X32 = 0x20, + X64 = 0x40 } export enum VsyncMode { @@ -1171,7 +1176,7 @@ export class TextureInfo { public flags: TextureFlags = TextureFlagBit.NONE, public layerCount: number = 1, public levelCount: number = 1, - public samples: SampleCount = SampleCount.ONE, + public samples: SampleCount = SampleCount.X1, public depth: number = 1, public externalRes: number = 0, ) {} @@ -1513,7 +1518,7 @@ export class ColorAttachment { constructor ( public format: Format = Format.UNKNOWN, - public sampleCount: SampleCount = SampleCount.ONE, + public sampleCount: SampleCount = SampleCount.X1, public loadOp: LoadOp = LoadOp.CLEAR, public storeOp: StoreOp = StoreOp.STORE, public barrier: GeneralBarrier = null!, @@ -1534,7 +1539,7 @@ export class DepthStencilAttachment { constructor ( public format: Format = Format.UNKNOWN, - public sampleCount: SampleCount = SampleCount.ONE, + public sampleCount: SampleCount = SampleCount.X1, public depthLoadOp: LoadOp = LoadOp.CLEAR, public depthStoreOp: StoreOp = StoreOp.STORE, public stencilLoadOp: LoadOp = LoadOp.CLEAR, @@ -1608,6 +1613,7 @@ export class RenderPassInfo { constructor ( public colorAttachments: ColorAttachment[] = [], public depthStencilAttachment: DepthStencilAttachment = new DepthStencilAttachment(), + public depthStencilResolveAttachment: DepthStencilAttachment = new DepthStencilAttachment(), public subpasses: SubpassInfo[] = [], public dependencies: SubpassDependency[] = [], ) {} @@ -1615,6 +1621,7 @@ export class RenderPassInfo { public copy (info: Readonly) { deepCopy(this.colorAttachments, info.colorAttachments, ColorAttachment); this.depthStencilAttachment.copy(info.depthStencilAttachment); + this.depthStencilResolveAttachment.copy(info.depthStencilResolveAttachment); deepCopy(this.subpasses, info.subpasses, SubpassInfo); deepCopy(this.dependencies, info.dependencies, SubpassDependency); return this; @@ -1703,12 +1710,14 @@ export class FramebufferInfo { public renderPass: RenderPass = null!, public colorTextures: Texture[] = [], public depthStencilTexture: Texture | null = null, + public depthStencilResolveTexture: Texture | null = null, ) {} public copy (info: Readonly) { this.renderPass = info.renderPass; this.colorTextures = info.colorTextures.slice(); this.depthStencilTexture = info.depthStencilTexture; + this.depthStencilResolveTexture = info.depthStencilResolveTexture; return this; } } diff --git a/cocos/gfx/base/device.ts b/cocos/gfx/base/device.ts index cb6c1541d20..2d6aa63e53f 100644 --- a/cocos/gfx/base/device.ts +++ b/cocos/gfx/base/device.ts @@ -28,7 +28,7 @@ import { ShaderInfo, InputAssemblerInfo, RenderPassInfo, FramebufferInfo, DescriptorSetLayoutInfo, PipelineLayoutInfo, QueueInfo, BufferTextureCopy, DeviceInfo, DeviceCaps, GeneralBarrierInfo, TextureBarrierInfo, BufferBarrierInfo, SwapchainInfo, BindingMappingInfo, Format, FormatFeature, TextureType, TextureUsageBit, - TextureFlagBit, Offset, Extent, SampleCount, TextureSubresLayers, + TextureFlagBit, Offset, Extent, SampleCount, TextureSubresLayers, TextureUsage, TextureFlags, } from './define'; import { Buffer } from './buffer'; import { CommandBuffer } from './command-buffer'; @@ -359,6 +359,17 @@ export abstract class Device { * @param format The GFX format to be queried. */ public enableAutoBarrier (en: boolean) {} + + /** + * @en Get maximum supported sample count. + * @zh 获取最大可支持的 Samples 参数 + * @param format The GFX texture format. + * @param usage The GFX texture usage. + * @param flags The GFX texture create flags. + */ + public getMaxSampleCount (format: Format, usage: TextureUsage, flags: TextureFlags): SampleCount { + return SampleCount.X1; + } } export class DefaultResource { @@ -413,7 +424,7 @@ export class DefaultResource { 2, 2, TextureFlagBit.NONE, 1, 1, - SampleCount.ONE, + SampleCount.X1, 2, )); const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 2), new TextureSubresLayers(0, 0, 1)); diff --git a/cocos/gfx/webgl/webgl-commands.ts b/cocos/gfx/webgl/webgl-commands.ts index 17343c3a0a6..9ebe1a1ec91 100644 --- a/cocos/gfx/webgl/webgl-commands.ts +++ b/cocos/gfx/webgl/webgl-commands.ts @@ -179,7 +179,7 @@ export function GFXFormatToWebGLInternalFormat (format: Format, gl: WebGLRenderi case Format.DEPTH_STENCIL: return gl.DEPTH_STENCIL; default: { - console.error('Unsupported Format, convert to WebGL internal format failed.'); + error('Unsupported Format, convert to WebGL internal format failed.'); return gl.RGBA; } } @@ -261,7 +261,7 @@ export function GFXFormatToWebGLFormat (format: Format, gl: WebGLRenderingContex case Format.ASTC_SRGBA_12X12: return WebGLEXT.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; default: { - console.error('Unsupported Format, convert to WebGL format failed.'); + error('Unsupported Format, convert to WebGL format failed.'); return gl.RGBA; } } @@ -288,7 +288,7 @@ function GFXTypeToWebGLType (type: Type, gl: WebGLRenderingContext): GLenum { case Type.SAMPLER2D: return gl.SAMPLER_2D; case Type.SAMPLER_CUBE: return gl.SAMPLER_CUBE; default: { - console.error('Unsupported GLType, convert to GL type failed.'); + error('Unsupported GLType, convert to GL type failed.'); return Type.UNKNOWN; } } @@ -315,7 +315,7 @@ function GFXTypeToTypedArrayCtor (type: Type) { case Type.MAT4: return Float32Array; default: { - console.error('Unsupported GLType, convert to TypedArrayConstructor failed.'); + error('Unsupported GLType, convert to TypedArrayConstructor failed.'); return Float32Array; } } @@ -342,7 +342,7 @@ function WebGLTypeToGFXType (glType: GLenum, gl: WebGLRenderingContext): Type { case gl.SAMPLER_2D: return Type.SAMPLER2D; case gl.SAMPLER_CUBE: return Type.SAMPLER_CUBE; default: { - console.error('Unsupported GLType, convert to Type failed.'); + error('Unsupported GLType, convert to Type failed.'); return Type.UNKNOWN; } } @@ -369,7 +369,7 @@ function WebGLGetTypeSize (glType: GLenum, gl: WebGLRenderingContext): Type { case gl.SAMPLER_2D: return 4; case gl.SAMPLER_CUBE: return 4; default: { - console.error('Unsupported GLType, get type failed.'); + error('Unsupported GLType, get type failed.'); return 0; } } @@ -665,7 +665,7 @@ export function WebGLCmdFuncCreateBuffer (device: WebGLDevice, gpuBuffer: IWebGL } else if (gpuBuffer.usage & BufferUsageBit.TRANSFER_SRC) { gpuBuffer.glTarget = gl.NONE; } else { - console.error('Unsupported BufferType, create buffer failed.'); + error('Unsupported BufferType, create buffer failed.'); gpuBuffer.glTarget = gl.NONE; } } @@ -764,7 +764,7 @@ export function WebGLCmdFuncResizeBuffer (device: WebGLDevice, gpuBuffer: IWebGL || (gpuBuffer.usage & BufferUsageBit.TRANSFER_SRC)) { gpuBuffer.glTarget = gl.NONE; } else { - console.error('Unsupported BufferType, create buffer failed.'); + error('Unsupported BufferType, create buffer failed.'); gpuBuffer.glTarget = gl.NONE; } } @@ -820,7 +820,7 @@ export function WebGLCmdFuncUpdateBuffer (device: WebGLDevice, gpuBuffer: IWebGL break; } default: { - console.error('Unsupported BufferType, update buffer failed.'); + error('Unsupported BufferType, update buffer failed.'); return; } } @@ -967,7 +967,7 @@ export function WebGLCmdFuncCreateTexture (device: WebGLDevice, gpuTexture: IWeb break; } default: { - console.error('Unsupported TextureType, create texture failed.'); + error('Unsupported TextureType, create texture failed.'); gpuTexture.type = TextureType.TEX2D; gpuTexture.glTarget = gl.TEXTURE_2D; } @@ -1094,7 +1094,7 @@ export function WebGLCmdFuncResizeTexture (device: WebGLDevice, gpuTexture: IWeb break; } default: { - console.error('Unsupported TextureType, create texture failed.'); + error('Unsupported TextureType, create texture failed.'); gpuTexture.type = TextureType.TEX2D; gpuTexture.glTarget = gl.TEXTURE_2D; } @@ -1178,19 +1178,19 @@ export function WebGLCmdFuncCreateFramebuffer (device: WebGLDevice, gpuFramebuff if (status !== gl.FRAMEBUFFER_COMPLETE) { switch (status) { case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT'); break; } case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'); break; } case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS'); break; } case gl.FRAMEBUFFER_UNSUPPORTED: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED'); break; } default: @@ -1236,7 +1236,7 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL break; } default: { - console.error('Unsupported ShaderType.'); + error('Unsupported ShaderType.'); return; } } @@ -1248,9 +1248,9 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL gl.compileShader(gpuStage.glShader); if (!gl.getShaderParameter(gpuStage.glShader, gl.COMPILE_STATUS)) { - console.error(`${shaderTypeStr} in '${gpuShader.name}' compilation failed.`); - console.error('Shader source dump:', gpuStage.source.replace(/^|\n/g, () => `\n${lineNumber++} `)); - console.error(gl.getShaderInfoLog(gpuStage.glShader)); + error(`${shaderTypeStr} in '${gpuShader.name}' compilation failed.`); + error('Shader source dump:', gpuStage.source.replace(/^|\n/g, () => `\n${lineNumber++} `)); + error(gl.getShaderInfoLog(gpuStage.glShader)); for (let l = 0; l < gpuShader.gpuStages.length; l++) { const stage = gpuShader.gpuStages[k]; @@ -1294,8 +1294,8 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL if (gl.getProgramParameter(gpuShader.glProgram, gl.LINK_STATUS)) { debug(`Shader '${gpuShader.name}' compilation succeeded.`); } else { - console.error(`Failed to link shader '${gpuShader.name}'.`); - console.error(gl.getProgramInfoLog(gpuShader.glProgram)); + error(`Failed to link shader '${gpuShader.name}'.`); + error(gl.getProgramInfoLog(gpuShader.glProgram)); return; } @@ -2735,7 +2735,7 @@ export function WebGLCmdFuncCopyTexImagesToTexture ( break; } default: { - console.error('Unsupported GL texture type, copy buffer to texture failed.'); + error('Unsupported GL texture type, copy buffer to texture failed.'); } } @@ -2906,7 +2906,7 @@ export function WebGLCmdFuncCopyBuffersToTexture ( break; } default: { - console.error('Unsupported GL texture type, copy buffer to texture failed.'); + error('Unsupported GL texture type, copy buffer to texture failed.'); } } @@ -2945,7 +2945,7 @@ export function WebGLCmdFuncCopyTextureToBuffers ( break; } default: { - console.error('Unsupported GL texture type, copy texture to buffers failed.'); + error('Unsupported GL texture type, copy texture to buffers failed.'); } } gl.bindFramebuffer(gl.FRAMEBUFFER, null); diff --git a/cocos/gfx/webgl2/webgl2-commands.ts b/cocos/gfx/webgl2/webgl2-commands.ts index 85405ec8b48..72c720da080 100644 --- a/cocos/gfx/webgl2/webgl2-commands.ts +++ b/cocos/gfx/webgl2/webgl2-commands.ts @@ -304,7 +304,7 @@ export function GFXFormatToWebGLInternalFormat (format: Format, gl: WebGL2Render case Format.ASTC_SRGBA_12X12: return WebGL2EXT.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; default: { - console.error('Unsupported Format, convert to WebGL internal format failed.'); + error('Unsupported Format, convert to WebGL internal format failed.'); return gl.RGBA; } } @@ -423,7 +423,7 @@ export function GFXFormatToWebGLFormat (format: Format, gl: WebGL2RenderingConte case Format.ASTC_SRGBA_12X12: return WebGL2EXT.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; default: { - console.error('Unsupported Format, convert to WebGL format failed.'); + error('Unsupported Format, convert to WebGL format failed.'); return gl.RGBA; } } @@ -458,7 +458,7 @@ function GFXTypeToWebGLType (type: Type, gl: WebGL2RenderingContext): GLenum { case Type.SAMPLER3D: return gl.SAMPLER_3D; case Type.SAMPLER_CUBE: return gl.SAMPLER_CUBE; default: { - console.error('Unsupported GLType, convert to GL type failed.'); + error('Unsupported GLType, convert to GL type failed.'); return Type.UNKNOWN; } } @@ -496,7 +496,7 @@ function WebGLTypeToGFXType (glType: GLenum, gl: WebGL2RenderingContext): Type { case gl.SAMPLER_3D: return Type.SAMPLER3D; case gl.SAMPLER_CUBE: return Type.SAMPLER_CUBE; default: { - console.error('Unsupported GLType, convert to Type failed.'); + error('Unsupported GLType, convert to Type failed.'); return Type.UNKNOWN; } } @@ -543,7 +543,7 @@ function WebGLGetTypeSize (glType: GLenum, gl: WebGL2RenderingContext): Type { case gl.UNSIGNED_INT_SAMPLER_3D: return 4; case gl.UNSIGNED_INT_SAMPLER_CUBE: return 4; default: { - console.error('Unsupported GLType, get type failed.'); + error('Unsupported GLType, get type failed.'); return 0; } } @@ -855,7 +855,7 @@ export function WebGL2CmdFuncCreateBuffer (device: WebGL2Device, gpuBuffer: IWeb } else if (gpuBuffer.usage & BufferUsageBit.TRANSFER_SRC) { gpuBuffer.glTarget = gl.NONE; } else { - console.error('Unsupported BufferType, create buffer failed.'); + error('Unsupported BufferType, create buffer failed.'); gpuBuffer.glTarget = gl.NONE; } } @@ -962,7 +962,7 @@ export function WebGL2CmdFuncResizeBuffer (device: WebGL2Device, gpuBuffer: IWeb || (gpuBuffer.usage & BufferUsageBit.TRANSFER_SRC)) { gpuBuffer.glTarget = gl.NONE; } else { - console.error('Unsupported BufferType, create buffer failed.'); + error('Unsupported BufferType, create buffer failed.'); gpuBuffer.glTarget = gl.NONE; } } @@ -1037,7 +1037,7 @@ export function WebGL2CmdFuncUpdateBuffer (device: WebGL2Device, gpuBuffer: IWeb break; } default: { - console.error('Unsupported BufferType, update buffer failed.'); + error('Unsupported BufferType, update buffer failed.'); } } } @@ -1064,7 +1064,7 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW errorID(9100, maxSize, device.capabilities.maxTextureSize); } - if (gpuTexture.samples === SampleCount.ONE) { + if (gpuTexture.samples === SampleCount.X1) { gpuTexture.glTexture = gl.createTexture(); if (gpuTexture.size > 0) { const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; @@ -1199,7 +1199,7 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW break; } default: { - console.error('Unsupported TextureType, create texture failed.'); + error('Unsupported TextureType, create texture failed.'); gpuTexture.type = TextureType.TEX2D; gpuTexture.glTarget = gl.TEXTURE_2D; } @@ -1254,7 +1254,7 @@ export function WebGL2CmdFuncResizeTexture (device: WebGL2Device, gpuTexture: IW errorID(9100, maxSize, device.capabilities.maxTextureSize); } - if (gpuTexture.samples === SampleCount.ONE) { + if (gpuTexture.samples === SampleCount.X1) { const glTexUnit = device.stateCache.glTexUnits[device.stateCache.texUnit]; if (glTexUnit.glTexture !== gpuTexture.glTexture) { @@ -1387,7 +1387,7 @@ export function WebGL2CmdFuncResizeTexture (device: WebGL2Device, gpuTexture: IW break; } default: { - console.error('Unsupported TextureType, create texture failed.'); + error('Unsupported TextureType, create texture failed.'); gpuTexture.type = TextureType.TEX2D; gpuTexture.glTarget = gl.TEXTURE_2D; } @@ -1521,19 +1521,19 @@ export function WebGL2CmdFuncCreateFramebuffer (device: WebGL2Device, gpuFramebu if (status !== gl.FRAMEBUFFER_COMPLETE) { switch (status) { case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT'); break; } case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'); break; } case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS'); break; } case gl.FRAMEBUFFER_UNSUPPORTED: { - console.error('glCheckFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED'); + error('glCheckFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED'); break; } default: @@ -1579,7 +1579,7 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb break; } default: { - console.error('Unsupported ShaderType.'); + error('Unsupported ShaderType.'); return; } } @@ -1591,9 +1591,9 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb gl.compileShader(gpuStage.glShader); if (!gl.getShaderParameter(gpuStage.glShader, gl.COMPILE_STATUS)) { - console.error(`${shaderTypeStr} in '${gpuShader.name}' compilation failed.`); - console.error('Shader source dump:', gpuStage.source.replace(/^|\n/g, () => `\n${lineNumber++} `)); - console.error(gl.getShaderInfoLog(gpuStage.glShader)); + error(`${shaderTypeStr} in '${gpuShader.name}' compilation failed.`); + error('Shader source dump:', gpuStage.source.replace(/^|\n/g, () => `\n${lineNumber++} `)); + error(gl.getShaderInfoLog(gpuStage.glShader)); for (let l = 0; l < gpuShader.gpuStages.length; l++) { const stage = gpuShader.gpuStages[k]; @@ -1637,8 +1637,8 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb if (gl.getProgramParameter(gpuShader.glProgram, gl.LINK_STATUS)) { debug(`Shader '${gpuShader.name}' compilation succeeded.`); } else { - console.error(`Failed to link shader '${gpuShader.name}'.`); - console.error(gl.getProgramInfoLog(gpuShader.glProgram)); + error(`Failed to link shader '${gpuShader.name}'.`); + error(gl.getProgramInfoLog(gpuShader.glProgram)); return; } @@ -2814,7 +2814,7 @@ export function WebGL2CmdFuncCopyTexImagesToTexture ( break; } default: { - console.error('Unsupported GL texture type, copy buffer to texture failed.'); + error('Unsupported GL texture type, copy buffer to texture failed.'); } } @@ -3086,7 +3086,7 @@ export function WebGL2CmdFuncCopyBuffersToTexture ( break; } default: { - console.error('Unsupported GL texture type, copy buffer to texture failed.'); + error('Unsupported GL texture type, copy buffer to texture failed.'); } } @@ -3125,7 +3125,7 @@ export function WebGL2CmdFuncCopyTextureToBuffers ( break; } default: { - console.error('Unsupported GL texture type, copy texture to buffers failed.'); + error('Unsupported GL texture type, copy texture to buffers failed.'); } } gl.bindFramebuffer(gl.FRAMEBUFFER, null); diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index 285fc02d679..61c80a61ac1 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -20,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************************************************************/ + ****************************************************************************/ /** * ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! ========================= @@ -32,9 +32,41 @@ import { getPhaseID, InstancedBuffer, PipelineStateManager } from '..'; import { assert, cclegacy, RecyclePool } from '../../core'; import intersect from '../../core/geometry/intersect'; import { Sphere } from '../../core/geometry/sphere'; -import { AccessFlagBit, Attribute, Buffer, BufferInfo, BufferUsageBit, BufferViewInfo, Color, ColorAttachment, CommandBuffer, DepthStencilAttachment, DescriptorSet, DescriptorSetInfo, Device, deviceManager, Format, Framebuffer, - FramebufferInfo, GeneralBarrierInfo, InputAssemblerInfo, LoadOp, MemoryUsageBit, PipelineState, Rect, RenderPass, RenderPassInfo, Sampler, SamplerInfo, StoreOp, SurfaceTransform, Swapchain, Texture, TextureInfo, - TextureType, TextureUsageBit, Viewport } from '../../gfx'; +import { + AccessFlagBit, + Attribute, + Buffer, + BufferInfo, + BufferUsageBit, + BufferViewInfo, + Color, + ColorAttachment, + CommandBuffer, + DepthStencilAttachment, + DescriptorSet, + DescriptorSetInfo, + Device, + deviceManager, + Format, + Framebuffer, + FramebufferInfo, + GeneralBarrierInfo, + InputAssemblerInfo, + LoadOp, + MemoryUsageBit, + PipelineState, + Rect, + RenderPass, + RenderPassInfo, + StoreOp, + SurfaceTransform, + Swapchain, + Texture, + TextureInfo, + TextureType, + TextureUsageBit, + Viewport, +} from '../../gfx'; import { legacyCC } from '../../core/global-exports'; import { Vec3 } from '../../core/math/vec3'; import { Vec4 } from '../../core/math/vec4'; @@ -47,10 +79,45 @@ import { PipelineSceneData } from '../pipeline-scene-data'; import { PipelineInputAssemblerData } from '../render-pipeline'; import { DescriptorSetData, LayoutGraphData, PipelineLayoutData, RenderPhaseData, RenderStageData } from './layout-graph'; import { BasicPipeline, SceneVisitor } from './pipeline'; -import { Blit, ClearView, ComputePass, ComputeSubpass, CopyPass, Dispatch, FormatView, ManagedBuffer, ManagedResource, ManagedTexture, MovePass, - RasterPass, RasterSubpass, RaytracePass, RenderData, RenderGraph, RenderGraphVisitor, RenderQueue, RenderSwapchain, ResolvePass, ResourceDesc, - ResourceGraph, ResourceGraphVisitor, ResourceTraits, SceneData, SubresourceView, ComputeView, RasterView } from './render-graph'; -import { AttachmentType, QueueHint, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; +import { + Blit, + ClearView, + ComputePass, + ComputeSubpass, + ComputeView, + CopyPass, + Dispatch, + FormatView, + ManagedBuffer, + ManagedResource, + ManagedTexture, + MovePass, + RasterPass, + RasterSubpass, + RasterView, + RaytracePass, + RenderData, + RenderGraph, + RenderGraphVisitor, + RenderQueue, + RenderSwapchain, + ResolvePass, + ResourceDesc, + ResourceGraph, + ResourceGraphVisitor, + ResourceTraits, + SceneData, + SubresourceView, +} from './render-graph'; +import { + AttachmentType, + QueueHint, + ResourceDimension, + ResourceFlags, + ResourceResidency, + SceneFlags, + UpdateFrequency, +} from './types'; import { PipelineUBO } from '../pipeline-ubo'; import { RenderInfo, RenderObject, WebSceneTask, WebSceneTransversal } from './web-scene'; import { WebSceneVisitor } from './web-scene-visitor'; @@ -59,7 +126,14 @@ import { RenderShadowMapBatchedQueue } from '../render-shadow-map-batched-queue' import { PlanarShadowQueue } from '../planar-shadow-queue'; import { DefaultVisitor, depthFirstSearch, ReferenceGraphView } from './graph'; import { VectorGraphColorMap } from './effect'; -import { getDescBindingFromName, getDescriptorSetDataFromLayout, getDescriptorSetDataFromLayoutId, getRenderArea, mergeSrcToTargetDesc, updateGlobalDescBinding } from './define'; +import { + getDescBindingFromName, + getDescriptorSetDataFromLayout, + getDescriptorSetDataFromLayoutId, + getRenderArea, + mergeSrcToTargetDesc, + updateGlobalDescBinding, +} from './define'; import { RenderReflectionProbeQueue } from '../render-reflection-probe-queue'; import { builtinResMgr } from '../../asset/asset-manager/builtin-res-mgr'; import { Texture2D } from '../../asset/assets/texture-2d'; @@ -177,6 +251,8 @@ class DeviceTexture extends DeviceResource { if (info.flags & ResourceFlags.INPUT_ATTACHMENT) usageFlags |= TextureUsageBit.INPUT_ATTACHMENT; if (info.flags & ResourceFlags.SAMPLED) usageFlags |= TextureUsageBit.SAMPLED; if (info.flags & ResourceFlags.STORAGE) usageFlags |= TextureUsageBit.STORAGE; + if (info.flags & ResourceFlags.TRANSFER_SRC) usageFlags |= TextureUsageBit.TRANSFER_SRC; + if (info.flags & ResourceFlags.TRANSFER_DST) usageFlags |= TextureUsageBit.TRANSFER_DST; this._texture = context.device.createTexture(new TextureInfo( type, diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index 93e33253156..6c6640cbf34 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -114,7 +114,7 @@ export class ResourceDesc { depthOrArraySize = 0; mipLevels = 0; format: Format = Format.UNKNOWN; - sampleCount: SampleCount = SampleCount.ONE; + sampleCount: SampleCount = SampleCount.X1; textureFlags: TextureFlagBit = TextureFlagBit.NONE; flags: ResourceFlags = ResourceFlags.NONE; } diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index d2ab00e415a..05120880f29 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -168,6 +168,8 @@ export enum ResourceFlags { DEPTH_STENCIL_ATTACHMENT = 0x20, INPUT_ATTACHMENT = 0x40, SHADING_RATE = 0x80, + TRANSFER_SRC = 0x100, + TRANSFER_DST = 0x200 } export enum TaskType { diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 5fee47004f1..8492ab70ce9 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -1675,7 +1675,7 @@ export class WebPipeline implements BasicPipeline { desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = SampleCount.ONE; + desc.sampleCount = SampleCount.X1; desc.flags = ResourceFlags.COLOR_ATTACHMENT | ResourceFlags.SAMPLED; return this._resourceGraph.addVertex( @@ -1695,7 +1695,7 @@ export class WebPipeline implements BasicPipeline { desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = SampleCount.ONE; + desc.sampleCount = SampleCount.X1; desc.flags = ResourceFlags.DEPTH_STENCIL_ATTACHMENT | ResourceFlags.SAMPLED; return this._resourceGraph.addVertex( ResourceGraphValue.Managed, diff --git a/native/cocos/core/assets/RenderTexture.cpp b/native/cocos/core/assets/RenderTexture.cpp index 79224297f73..564e94cb923 100644 --- a/native/cocos/core/assets/RenderTexture.cpp +++ b/native/cocos/core/assets/RenderTexture.cpp @@ -36,7 +36,7 @@ gfx::RenderPassInfo getDefaultRenderPassInfo(gfx::Device *device) { gfx::RenderPassInfo info; info.colorAttachments.push_back({ gfx::Format::RGBA8, - gfx::SampleCount::ONE, + gfx::SampleCount::X1, gfx::LoadOp::CLEAR, gfx::StoreOp::STORE, device->getGeneralBarrier({ diff --git a/native/cocos/renderer/frame-graph/FrameGraph.cpp b/native/cocos/renderer/frame-graph/FrameGraph.cpp index 25b14f79e09..594d16a0c9b 100644 --- a/native/cocos/renderer/frame-graph/FrameGraph.cpp +++ b/native/cocos/renderer/frame-graph/FrameGraph.cpp @@ -426,7 +426,7 @@ void FrameGraph::computeStoreActionAndMemoryless() { const gfx::TextureInfo &textureDesc = static_cast *>(renderTarget)->get().getDesc(); renderTarget->_memoryless = renderTarget->_neverLoaded && renderTarget->_neverStored; - renderTarget->_memorylessMSAA = textureDesc.samples != gfx::SampleCount::ONE && renderTarget->_writerCount < 2; + renderTarget->_memorylessMSAA = textureDesc.samples != gfx::SampleCount::X1 && renderTarget->_writerCount < 2; } } diff --git a/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp b/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp index 204df36fafa..7689387fd31 100644 --- a/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp +++ b/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp @@ -383,6 +383,27 @@ void CommandBufferAgent::updateBuffer(Buffer *buff, const void *data, uint32_t s }); } +void CommandBufferAgent::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + Texture *actorSrcTexture = nullptr; + Texture *actorDstTexture = nullptr; + if (srcTexture) actorSrcTexture = static_cast(srcTexture)->getActor(); + if (dstTexture) actorDstTexture = static_cast(dstTexture)->getActor(); + + auto *actorRegions = _messageQueue->allocate(count); + memcpy(actorRegions, regions, count * sizeof(TextureCopy)); + + ENQUEUE_MESSAGE_5( + _messageQueue, CommandBufferBlitTexture, + actor, getActor(), + srcTexture, actorSrcTexture, + dstTexture, actorDstTexture, + regions, actorRegions, + count, count, + { + actor->resolveTexture(srcTexture, dstTexture, regions, count); + }); +} + void CommandBufferAgent::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { Texture *actorSrcTexture = nullptr; Texture *actorDstTexture = nullptr; diff --git a/native/cocos/renderer/gfx-agent/CommandBufferAgent.h b/native/cocos/renderer/gfx-agent/CommandBufferAgent.h index 95ddf92a57f..b3cf37ff0e8 100644 --- a/native/cocos/renderer/gfx-agent/CommandBufferAgent.h +++ b/native/cocos/renderer/gfx-agent/CommandBufferAgent.h @@ -61,6 +61,7 @@ class CC_DLL CommandBufferAgent final : public Agent { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-agent/DeviceAgent.cpp b/native/cocos/renderer/gfx-agent/DeviceAgent.cpp index 16fe3f531e7..872fb3bf849 100644 --- a/native/cocos/renderer/gfx-agent/DeviceAgent.cpp +++ b/native/cocos/renderer/gfx-agent/DeviceAgent.cpp @@ -455,5 +455,9 @@ void DeviceAgent::frameSync() { }); } +SampleCount DeviceAgent::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + return _actor->getMaxSampleCount(format, usage, flags); +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-agent/DeviceAgent.h b/native/cocos/renderer/gfx-agent/DeviceAgent.h index cbbb9693467..ce11e0feb5b 100644 --- a/native/cocos/renderer/gfx-agent/DeviceAgent.h +++ b/native/cocos/renderer/gfx-agent/DeviceAgent.h @@ -106,7 +106,7 @@ class CC_DLL DeviceAgent final : public Agent { void presentSignal(); void enableAutoBarrier(bool en) override; - + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; protected: static DeviceAgent *instance; diff --git a/native/cocos/renderer/gfx-agent/FramebufferAgent.cpp b/native/cocos/renderer/gfx-agent/FramebufferAgent.cpp index 0c54378d084..8b3f0191408 100644 --- a/native/cocos/renderer/gfx-agent/FramebufferAgent.cpp +++ b/native/cocos/renderer/gfx-agent/FramebufferAgent.cpp @@ -57,6 +57,9 @@ void FramebufferAgent::doInit(const FramebufferInfo &info) { if (info.depthStencilTexture) { actorInfo.depthStencilTexture = static_cast(info.depthStencilTexture)->getActor(); } + if (info.depthStencilResolveTexture) { + actorInfo.depthStencilResolveTexture = static_cast(info.depthStencilResolveTexture)->getActor(); + } actorInfo.renderPass = static_cast(info.renderPass)->getActor(); ENQUEUE_MESSAGE_2( diff --git a/native/cocos/renderer/gfx-base/GFXCommandBuffer.h b/native/cocos/renderer/gfx-base/GFXCommandBuffer.h index c16065c74b2..00a6d46e2aa 100644 --- a/native/cocos/renderer/gfx-base/GFXCommandBuffer.h +++ b/native/cocos/renderer/gfx-base/GFXCommandBuffer.h @@ -63,6 +63,7 @@ class CC_DLL CommandBuffer : public GFXObject, public RefCounted { virtual void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) = 0; virtual void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) = 0; virtual void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0; + virtual void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0; virtual void execute(CommandBuffer *const *cmdBuffs, uint32_t count) = 0; virtual void dispatch(const DispatchInfo &info) = 0; virtual void beginQuery(QueryPool *queryPool, uint32_t id) = 0; diff --git a/native/cocos/renderer/gfx-base/GFXDef-common.h b/native/cocos/renderer/gfx-base/GFXDef-common.h index 943cc1242c1..f82b5604df8 100644 --- a/native/cocos/renderer/gfx-base/GFXDef-common.h +++ b/native/cocos/renderer/gfx-base/GFXDef-common.h @@ -173,11 +173,13 @@ enum class Feature : uint32_t { MULTIPLE_RENDER_TARGETS, BLEND_MINMAX, COMPUTE_SHADER, - // @deprecated - INPUT_ATTACHMENT_BENEFIT, + + INPUT_ATTACHMENT_BENEFIT, // @deprecated SUBPASS_COLOR_INPUT, SUBPASS_DEPTH_STENCIL_INPUT, RASTERIZATION_ORDER_NOCOHERENT, + + MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL, // resolve depth stencil COUNT, }; CC_ENUM_CONVERSION_OPERATOR(Feature); @@ -472,9 +474,10 @@ CC_ENUM_BITWISE_OPERATORS(TextureUsageBit); enum class TextureFlagBit : uint32_t { NONE = 0, GEN_MIPMAP = 0x1, // Generate mipmaps using bilinear filter - GENERAL_LAYOUT = 0x2, // For inout framebuffer attachments + GENERAL_LAYOUT = 0x2, // @deprecated, For inout framebuffer attachments EXTERNAL_OES = 0x4, // External oes texture EXTERNAL_NORMAL = 0x8, // External normal texture + LAZILY_ALLOCATED = 0x10 // Try lazily allocated mode. }; using TextureFlags = TextureFlagBit; CC_ENUM_BITWISE_OPERATORS(TextureFlagBit); @@ -492,10 +495,13 @@ using FormatFeature = FormatFeatureBit; CC_ENUM_BITWISE_OPERATORS(FormatFeatureBit); enum class SampleCount : uint32_t { - ONE, // Single sample - MULTIPLE_PERFORMANCE, // Multiple samples prioritizing performance over quality - MULTIPLE_BALANCE, // Multiple samples leveraging both quality and performance - MULTIPLE_QUALITY, // Multiple samples prioritizing quality over performance + X1 = 0x01, + X2 = 0x02, + X4 = 0x04, + X8 = 0x08, + X16 = 0x10, + X32 = 0x20, + X64 = 0x40 }; CC_ENUM_CONVERSION_OPERATOR(SampleCount); @@ -1064,7 +1070,7 @@ struct ALIGNAS(8) TextureInfo { TextureFlags flags{TextureFlagBit::NONE}; uint32_t layerCount{1}; uint32_t levelCount{1}; - SampleCount samples{SampleCount::ONE}; + SampleCount samples{SampleCount::X1}; uint32_t depth{1}; void *externalRes{nullptr}; // CVPixelBuffer for Metal, EGLImage for GLES #if CC_CPU_ARCH == CC_CPU_ARCH_32 @@ -1272,7 +1278,7 @@ struct InputAssemblerInfo { struct ALIGNAS(8) ColorAttachment { Format format{Format::UNKNOWN}; - SampleCount sampleCount{SampleCount::ONE}; + SampleCount sampleCount{SampleCount::X1}; LoadOp loadOp{LoadOp::CLEAR}; StoreOp storeOp{StoreOp::STORE}; GeneralBarrier *barrier{nullptr}; @@ -1284,7 +1290,7 @@ using ColorAttachmentList = ccstd::vector; struct ALIGNAS(8) DepthStencilAttachment { Format format{Format::UNKNOWN}; - SampleCount sampleCount{SampleCount::ONE}; + SampleCount sampleCount{SampleCount::X1}; LoadOp depthLoadOp{LoadOp::CLEAR}; StoreOp depthStoreOp{StoreOp::STORE}; LoadOp stencilLoadOp{LoadOp::CLEAR}; @@ -1327,6 +1333,7 @@ using SubpassDependencyList = ccstd::vector; struct RenderPassInfo { ColorAttachmentList colorAttachments; DepthStencilAttachment depthStencilAttachment; + DepthStencilAttachment depthStencilResolveAttachment; SubpassInfoList subpasses; SubpassDependencyList dependencies; @@ -1386,6 +1393,7 @@ struct FramebufferInfo { RenderPass *renderPass{nullptr}; TextureList colorTextures; Texture *depthStencilTexture{nullptr}; // @ts-nullable + Texture *depthStencilResolveTexture{nullptr}; // @ts-nullable EXPOSE_COPY_FN(FramebufferInfo) }; diff --git a/native/cocos/renderer/gfx-base/GFXDef.cpp b/native/cocos/renderer/gfx-base/GFXDef.cpp index c7e35253f44..00a9bc6873e 100644 --- a/native/cocos/renderer/gfx-base/GFXDef.cpp +++ b/native/cocos/renderer/gfx-base/GFXDef.cpp @@ -107,6 +107,7 @@ ccstd::hash_t Hasher::operator()(const RenderPassInfo &info) con ccstd::hash_t seed = 4; ccstd::hash_combine(seed, info.colorAttachments); ccstd::hash_combine(seed, info.depthStencilAttachment); + ccstd::hash_combine(seed, info.depthStencilResolveAttachment); ccstd::hash_combine(seed, info.subpasses); ccstd::hash_combine(seed, info.dependencies); return seed; @@ -115,6 +116,7 @@ ccstd::hash_t Hasher::operator()(const RenderPassInfo &info) con bool operator==(const RenderPassInfo &lhs, const RenderPassInfo &rhs) { return lhs.colorAttachments == rhs.colorAttachments && lhs.depthStencilAttachment == rhs.depthStencilAttachment && + lhs.depthStencilResolveAttachment == rhs.depthStencilResolveAttachment && lhs.subpasses == rhs.subpasses && lhs.dependencies == rhs.dependencies; } @@ -122,19 +124,17 @@ bool operator==(const RenderPassInfo &lhs, const RenderPassInfo &rhs) { template <> ccstd::hash_t Hasher::operator()(const FramebufferInfo &info) const { // render pass is mostly irrelevant - ccstd::hash_t seed; + ccstd::hash_t seed = static_cast(info.colorTextures.size()) + + static_cast(info.depthStencilTexture != nullptr) + + static_cast(info.depthStencilResolveTexture != nullptr); if (info.depthStencilTexture) { - seed = (static_cast(info.colorTextures.size()) + 1) * 3 + 1; - ccstd::hash_combine(seed, info.depthStencilTexture); - ccstd::hash_combine(seed, info.depthStencilTexture->getRaw()); - ccstd::hash_combine(seed, info.depthStencilTexture->getHash()); - } else { - seed = static_cast(info.colorTextures.size()) * 3 + 1; + ccstd::hash_combine(seed, info.depthStencilTexture->getObjectID()); + } + if (info.depthStencilResolveTexture) { + ccstd::hash_combine(seed, info.depthStencilResolveTexture->getObjectID()); } for (auto *colorTexture : info.colorTextures) { - ccstd::hash_combine(seed, colorTexture); - ccstd::hash_combine(seed, colorTexture->getRaw()); - ccstd::hash_combine(seed, colorTexture->getHash()); + ccstd::hash_combine(seed, colorTexture->getObjectID()); } ccstd::hash_combine(seed, info.renderPass->getHash()); return seed; @@ -149,6 +149,10 @@ bool operator==(const FramebufferInfo &lhs, const FramebufferInfo &rhs) { res = lhs.depthStencilTexture == rhs.depthStencilTexture; } + if (res) { + res = lhs.depthStencilResolveTexture == rhs.depthStencilResolveTexture; + } + if (res) { for (size_t i = 0; i < lhs.colorTextures.size(); ++i) { res = lhs.colorTextures[i]->getRaw() == rhs.colorTextures[i]->getRaw() && diff --git a/native/cocos/renderer/gfx-base/GFXDevice.cpp b/native/cocos/renderer/gfx-base/GFXDevice.cpp index c8e8805d26a..a19e4da5198 100644 --- a/native/cocos/renderer/gfx-base/GFXDevice.cpp +++ b/native/cocos/renderer/gfx-base/GFXDevice.cpp @@ -154,7 +154,7 @@ DefaultResource::DefaultResource(Device *device) { if (device->getCapabilities().max3DTextureSize >= 2) { _texture3D = device->createTexture({TextureType::TEX3D, TextureUsageBit::STORAGE | TextureUsageBit::SAMPLED | TextureUsageBit::TRANSFER_DST, - Format::RGBA8, 2, 2, TextureFlagBit::NONE, 1, 1, SampleCount::ONE, 2}); + Format::RGBA8, 2, 2, TextureFlagBit::NONE, 1, 1, SampleCount::X1, 2}); BufferTextureCopy region = {0, 0, 0, {0, 0, 0}, {2, 2, 2}, {0, 0, 1}}; device->copyBuffersToTexture(&bufferData, _texture3D, ®ion, 1); } diff --git a/native/cocos/renderer/gfx-base/GFXDevice.h b/native/cocos/renderer/gfx-base/GFXDevice.h index c9f2c3f9efe..e59e8c5041e 100644 --- a/native/cocos/renderer/gfx-base/GFXDevice.h +++ b/native/cocos/renderer/gfx-base/GFXDevice.h @@ -57,7 +57,7 @@ class CC_DLL Device : public RefCounted { bool initialize(const DeviceInfo &info); void destroy(); - + // aim to ensure waiting for work on gpu done when cpu encodes ahead of gpu certain frame(s). virtual void frameSync() = 0; @@ -122,6 +122,12 @@ class CC_DLL Device : public RefCounted { void registerOnAcquireCallback(ExecuteMethod &&execute); virtual void enableAutoBarrier(bool en) { _options.enableBarrierDeduce = en; } + virtual SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + std::ignore = format; + std::ignore = usage; + std::ignore = flags; + return SampleCount::X1; + }; protected: static Device *instance; diff --git a/native/cocos/renderer/gfx-base/GFXFramebuffer.cpp b/native/cocos/renderer/gfx-base/GFXFramebuffer.cpp index 1fd8b6cce16..dfbdd20430c 100644 --- a/native/cocos/renderer/gfx-base/GFXFramebuffer.cpp +++ b/native/cocos/renderer/gfx-base/GFXFramebuffer.cpp @@ -44,6 +44,7 @@ void Framebuffer::initialize(const FramebufferInfo &info) { _renderPass = info.renderPass; _colorTextures = info.colorTextures; _depthStencilTexture = info.depthStencilTexture; + _depthStencilResolveTexture = info.depthStencilResolveTexture; doInit(info); } @@ -54,6 +55,7 @@ void Framebuffer::destroy() { _renderPass = nullptr; _colorTextures.clear(); _depthStencilTexture = nullptr; + _depthStencilResolveTexture = nullptr; } } // namespace gfx diff --git a/native/cocos/renderer/gfx-base/GFXFramebuffer.h b/native/cocos/renderer/gfx-base/GFXFramebuffer.h index 01a8b3a925b..21125fc1607 100644 --- a/native/cocos/renderer/gfx-base/GFXFramebuffer.h +++ b/native/cocos/renderer/gfx-base/GFXFramebuffer.h @@ -45,6 +45,7 @@ class CC_DLL Framebuffer : public GFXObject, public RefCounted { inline RenderPass *getRenderPass() const { return _renderPass; } inline const TextureList &getColorTextures() const { return _colorTextures; } inline Texture *getDepthStencilTexture() const { return _depthStencilTexture; } + inline Texture *getDepthStencilResolveTexture() const { return _depthStencilResolveTexture; } protected: virtual void doInit(const FramebufferInfo &info) = 0; @@ -56,6 +57,7 @@ class CC_DLL Framebuffer : public GFXObject, public RefCounted { TextureList _colorTextures; // weak reference Texture *_depthStencilTexture{nullptr}; + Texture *_depthStencilResolveTexture{nullptr}; }; } // namespace gfx diff --git a/native/cocos/renderer/gfx-base/GFXRenderPass.cpp b/native/cocos/renderer/gfx-base/GFXRenderPass.cpp index 7dff13380dd..91cb468c246 100644 --- a/native/cocos/renderer/gfx-base/GFXRenderPass.cpp +++ b/native/cocos/renderer/gfx-base/GFXRenderPass.cpp @@ -44,8 +44,8 @@ ccstd::hash_t RenderPass::computeHash() { for (const ColorAttachment &ca : _colorAttachments) { ccstd::hash_combine(seed, ca); } - const auto &ds = _depthStencilAttachment; - ccstd::hash_combine(seed, ds); + ccstd::hash_combine(seed, _depthStencilAttachment); + ccstd::hash_combine(seed, _depthStencilResolveAttachment); ccstd::hash_combine(seed, _subpasses); return seed; @@ -58,6 +58,7 @@ ccstd::hash_t RenderPass::computeHash(const RenderPassInfo &info) { void RenderPass::initialize(const RenderPassInfo &info) { _colorAttachments = info.colorAttachments; _depthStencilAttachment = info.depthStencilAttachment; + _depthStencilResolveAttachment = info.depthStencilResolveAttachment; _subpasses = info.subpasses; _dependencies = info.dependencies; _hash = computeHash(); diff --git a/native/cocos/renderer/gfx-base/GFXRenderPass.h b/native/cocos/renderer/gfx-base/GFXRenderPass.h index 12d606ecf6a..f51502c6326 100644 --- a/native/cocos/renderer/gfx-base/GFXRenderPass.h +++ b/native/cocos/renderer/gfx-base/GFXRenderPass.h @@ -42,6 +42,7 @@ class CC_DLL RenderPass : public GFXObject, public RefCounted { inline const ColorAttachmentList &getColorAttachments() const { return _colorAttachments; } inline const DepthStencilAttachment &getDepthStencilAttachment() const { return _depthStencilAttachment; } + inline const DepthStencilAttachment &getDepthStencilResolveAttachment() const { return _depthStencilResolveAttachment; } inline const SubpassInfoList &getSubpasses() const { return _subpasses; } inline const SubpassDependencyList &getDependencies() const { return _dependencies; } inline ccstd::hash_t getHash() const { return _hash; } @@ -54,6 +55,7 @@ class CC_DLL RenderPass : public GFXObject, public RefCounted { ColorAttachmentList _colorAttachments; DepthStencilAttachment _depthStencilAttachment; + DepthStencilAttachment _depthStencilResolveAttachment; SubpassInfoList _subpasses; SubpassDependencyList _dependencies; ccstd::hash_t _hash = 0; diff --git a/native/cocos/renderer/gfx-base/GFXTexture.cpp b/native/cocos/renderer/gfx-base/GFXTexture.cpp index d8b6a7cde05..36845612a6d 100644 --- a/native/cocos/renderer/gfx-base/GFXTexture.cpp +++ b/native/cocos/renderer/gfx-base/GFXTexture.cpp @@ -128,7 +128,7 @@ void Texture::updateTextureInfo(const SwapchainTextureInfo &info, Texture *out) out->_info.layerCount = 1; out->_info.levelCount = 1; out->_info.depth = 1; - out->_info.samples = SampleCount::ONE; + out->_info.samples = SampleCount::X1; out->_info.flags = TextureFlagBit::NONE; out->_info.usage = GFX_FORMAT_INFOS[toNumber(info.format)].hasDepth ? TextureUsageBit::DEPTH_STENCIL_ATTACHMENT diff --git a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp index 8db04e5f6fc..8c2e17a36b1 100644 --- a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp @@ -99,6 +99,9 @@ void EmptyCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, c void EmptyCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { } +void EmptyCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { +} + void EmptyCommandBuffer::dispatch(const DispatchInfo &info) { } diff --git a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h index f83d684b098..d429d23f61c 100644 --- a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h +++ b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h @@ -52,6 +52,7 @@ class CC_DLL EmptyCommandBuffer final : public CommandBuffer { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp index 5ee07a69a7c..daaf4efc6e9 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp @@ -316,6 +316,10 @@ void GLES2CommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, c // should not copy texture in a secondary command buffer } +void GLES2CommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + // should not copy texture in a secondary command buffer +} + void GLES2CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES2CmdBlitTexture *cmd = _cmdAllocator->blitTextureCmdPool.alloc(); if (srcTexture) cmd->gpuTextureSrc = static_cast(srcTexture)->gpuTexture(); diff --git a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h index 20e948ecbcf..06185861895 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h +++ b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h @@ -64,6 +64,7 @@ class CC_GLES2_API GLES2CommandBuffer : public CommandBuffer { void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override {} diff --git a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp index 2d7b38666fd..bf5895a2b3b 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp @@ -574,22 +574,13 @@ void cmdFuncGLES2CreateTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture) gpuTexture->glFormat = mapGLFormat(gpuTexture->format); gpuTexture->glType = formatToGLType(gpuTexture->format); gpuTexture->glInternalFmt = mapGLInternalFormat(gpuTexture->format); + gpuTexture->glSamples = static_cast(gpuTexture->samples); - if (gpuTexture->samples > SampleCount::ONE) { - if (device->constantRegistry()->mMSRT != MSRTSupportLevel::NONE) { - GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); - - auto requestedSampleCount = static_cast(gpuTexture->samples); - gpuTexture->glSamples = std::min(maxSamples, requestedSampleCount); - - // skip multi-sampled attachment resources if we can use auto resolve - if (gpuTexture->usage == TextureUsageBit::COLOR_ATTACHMENT) { - gpuTexture->memoryless = true; - return; - } - } else { - gpuTexture->glSamples = 1; // fallback to single sample if the extensions is not available + if (gpuTexture->samples > SampleCount::X1) { + if (device->constantRegistry()->mMSRT != MSRTSupportLevel::NONE && + hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED)) { + gpuTexture->allocateMemory = false; + return; } } @@ -810,7 +801,7 @@ void cmdFuncGLES2DestroyTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture } void cmdFuncGLES2ResizeTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture) { - if (gpuTexture->memoryless || gpuTexture->glTarget == GL_TEXTURE_EXTERNAL_OES) return; + if (!gpuTexture->allocateMemory || gpuTexture->glTarget == GL_TEXTURE_EXTERNAL_OES) return; if (gpuTexture->glSamples <= 1) { switch (gpuTexture->type) { @@ -3042,6 +3033,12 @@ void cmdFuncGLES2ExecuteCmds(GLES2Device *device, GLES2CmdPackage *cmdPackage) { } } +GLint cmdFuncGLES2GetMaxSampleCount() { + GLint maxSamples = 1; + GL_CHECK(glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples)); + return maxSamples; +} + void GLES2GPUBlitManager::initialize() { _gpuShader.name = "Blit Pass"; _gpuShader.blocks.push_back({ diff --git a/native/cocos/renderer/gfx-gles2/GLES2Commands.h b/native/cocos/renderer/gfx-gles2/GLES2Commands.h index e87736708f9..670b8e3ae34 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Commands.h +++ b/native/cocos/renderer/gfx-gles2/GLES2Commands.h @@ -246,5 +246,7 @@ void cmdFuncGLES2BlitTexture(GLES2Device *device, void cmdFuncGLES2ExecuteCmds(GLES2Device *device, GLES2CmdPackage *cmdPackage); +GLint cmdFuncGLES2GetMaxSampleCount(); + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-gles2/GLES2Device.cpp b/native/cocos/renderer/gfx-gles2/GLES2Device.cpp index 431aff68202..6d24d1b08bc 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Device.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Device.cpp @@ -176,6 +176,7 @@ bool GLES2Device::doInit(const DeviceInfo & /*info*/) { } } #endif + _features[toNumber(Feature::MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL)] = false; // not implement yet. ccstd::string compressedFmts; if (getFormatFeatures(Format::ETC_RGB8) != FormatFeature::NONE) { @@ -534,5 +535,12 @@ void GLES2Device::copyTextureToBuffers(Texture *src, uint8_t *const *buffers, co cmdFuncGLES2CopyTextureToBuffers(this, static_cast(src)->gpuTexture(), buffers, region, count); } +SampleCount GLES2Device::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + std::ignore = format; + std::ignore = usage; + std::ignore = flags; + return static_cast(cmdFuncGLES2GetMaxSampleCount()); +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-gles2/GLES2Device.h b/native/cocos/renderer/gfx-gles2/GLES2Device.h index 44867f653a8..0b7269005f0 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Device.h +++ b/native/cocos/renderer/gfx-gles2/GLES2Device.h @@ -95,7 +95,7 @@ class CC_GLES2_API GLES2Device final : public Device { // check the specified format is texture-exclusive (no renderbuffers allowed) inline bool isTextureExclusive(const Format &format) { return _textureExclusive[static_cast(format)]; }; - + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; protected: static GLES2Device *instance; diff --git a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h index 31057eec95b..7b252b240d0 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h +++ b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h @@ -118,10 +118,10 @@ struct GLES2GPUTexture { uint32_t size{0}; uint32_t arrayLayer{1}; uint32_t mipLevel{1}; - SampleCount samples{SampleCount::ONE}; + SampleCount samples{SampleCount::X1}; TextureFlags flags{TextureFlagBit::NONE}; bool isPowerOf2{false}; - bool memoryless{false}; + bool allocateMemory{true}; // false if swapchain image or implicit ms render buffer. GLenum glTarget{0}; GLenum glInternalFmt{0}; GLenum glFormat{0}; diff --git a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp index 6336745e101..1c3832849a8 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp @@ -149,6 +149,10 @@ void GLES2PrimaryCommandBuffer::copyBuffersToTexture(const uint8_t *const *buffe } } +void GLES2PrimaryCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + copyTexture(srcTexture, dstTexture, regions, count); +} + void GLES2PrimaryCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { GLES2GPUTexture *gpuTextureSrc = nullptr; GLES2GPUTexture *gpuTextureDst = nullptr; diff --git a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h index 358b3de968f..2a3411c9eef 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h +++ b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h @@ -46,6 +46,7 @@ class CC_GLES2_API GLES2PrimaryCommandBuffer final : public GLES2CommandBuffer { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; protected: diff --git a/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp b/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp index ad127f1557c..bfb6cc21809 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp @@ -59,7 +59,7 @@ void GLES2Texture::doInit(const TextureInfo & /*info*/) { cmdFuncGLES2CreateTexture(GLES2Device::getInstance(), _gpuTexture); - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES2Device::getInstance()->getMemoryStatus().textureSize += _size; CC_PROFILE_MEMORY_INC(Texture, _size); } @@ -72,7 +72,7 @@ void GLES2Texture::doInit(const TextureViewInfo &info) { void GLES2Texture::doDestroy() { if (_gpuTexture) { if (!_isTextureView) { - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -85,7 +85,7 @@ void GLES2Texture::doDestroy() { } void GLES2Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -97,7 +97,7 @@ void GLES2Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { GLES2Device::getInstance()->framebufferHub()->update(_gpuTexture); - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES2Device::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } @@ -135,7 +135,7 @@ void GLES2Texture::doInit(const SwapchainTextureInfo & /*info*/) { _gpuTexture->samples = _info.samples; _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; - _gpuTexture->memoryless = true; + _gpuTexture->allocateMemory = false; _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); } diff --git a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp index 6066660b980..706dd795a59 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp @@ -303,6 +303,10 @@ void GLES3CommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, c // should not copy texture in a secondary command buffer } +void GLES3CommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + // should not resolve texture in a secondary command buffer +} + void GLES3CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES3CmdBlitTexture *cmd = _cmdAllocator->blitTextureCmdPool.alloc(); if (srcTexture) cmd->gpuTextureSrc = static_cast(srcTexture)->gpuTexture(); diff --git a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h index 594a8e059f4..d42b50d43bc 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h +++ b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h @@ -64,6 +64,7 @@ class CC_GLES3_API GLES3CommandBuffer : public CommandBuffer { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const * /*buffers*/, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const * /*textures*/, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index c16915ff5a0..e54c79885d4 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -491,6 +491,18 @@ GLenum formatToGLType(Format format) { } } +GLenum getTextureTarget(TextureType type) { + switch (type) { + case TextureType::TEX2D: return GL_TEXTURE_2D; + case TextureType::TEX2D_ARRAY: return GL_TEXTURE_2D_ARRAY; + case TextureType::TEX3D: return GL_TEXTURE_3D; + case TextureType::CUBE: return GL_TEXTURE_CUBE_MAP; + default: + CC_ABORT(); + return GL_NONE; + } +} + uint32_t glComponentCount(GLenum glType) { switch (glType) { case GL_FLOAT_MAT2: @@ -575,17 +587,6 @@ const GLenum GL_MEMORY_ACCESS[] = { GL_WRITE_ONLY, GL_READ_WRITE, }; - -const GLint GL_SAMPLE_COUNT[] = { - 1, - 2, -#if CC_PLATFORM == CC_PLATFORM_ANDROID || CC_PLATFORM == CC_PLATFORM_IOS - 4, -#else - 8, -#endif - 16, -}; } // namespace void cmdFuncGLES3CreateBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer) { @@ -800,31 +801,78 @@ void cmdFuncGLES3ResizeBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer) { } } -void cmdFuncGLES3CreateTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) { - static ccstd::vector supportedSampleCounts; - - gpuTexture->glInternalFmt = mapGLInternalFormat(gpuTexture->format); - gpuTexture->glFormat = mapGLFormat(gpuTexture->format); - gpuTexture->glType = formatToGLType(gpuTexture->format); +static void renderBufferStorage(GLES3Device *device, GLES3GPUTexture *gpuTexture) { + CC_ASSERT(gpuTexture->type == TextureType::TEX2D); + GLuint &glRenderbuffer = device->stateCache()->glRenderbuffer; + if (gpuTexture->glRenderbuffer != glRenderbuffer) { + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, gpuTexture->glRenderbuffer)); + glRenderbuffer = gpuTexture->glRenderbuffer; + } + if (gpuTexture->glSamples > 1) { + GL_CHECK(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, gpuTexture->glSamples, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); + } else { + GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); + } +} - if (gpuTexture->samples > SampleCount::ONE) { - GLint supportedSampleCountCount = 0; - GL_CHECK(glGetInternalformativ(GL_RENDERBUFFER, gpuTexture->glInternalFmt, GL_SAMPLES, 1, &supportedSampleCountCount)); - supportedSampleCounts.resize(supportedSampleCountCount); - GL_CHECK(glGetInternalformativ(GL_RENDERBUFFER, gpuTexture->glInternalFmt, GL_SAMPLES, supportedSampleCountCount, supportedSampleCounts.data())); +static void textureStorage(GLES3Device *device, GLES3GPUTexture *gpuTexture) { + GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; - auto requestedSampleCount = GL_SAMPLE_COUNT[toNumber(gpuTexture->samples)]; - for (GLint sampleCount : supportedSampleCounts) { - if (sampleCount <= requestedSampleCount) { - gpuTexture->glSamples = sampleCount; - break; + if (gpuTexture->glTexture != glTexture) { + GL_CHECK(glBindTexture(gpuTexture->glTarget, gpuTexture->glTexture)); + glTexture = gpuTexture->glTexture; + } + uint32_t w = gpuTexture->width; + uint32_t h = gpuTexture->height; + uint32_t d = gpuTexture->type == TextureType::TEX2D_ARRAY ? gpuTexture->arrayLayer : gpuTexture->depth; + + switch (gpuTexture->type) { + case TextureType::CUBE: + CC_ASSERT(gpuTexture->glSamples <= 1); + case TextureType::TEX2D: + if (gpuTexture->glSamples > 1 && !gpuTexture->immutable && device->constantRegistry()->glMinorVersion >= 1) { + gpuTexture->glTarget = GL_TEXTURE_2D_MULTISAMPLE; + GL_CHECK(glTexStorage2DMultisample(gpuTexture->glTarget, gpuTexture->glSamples, gpuTexture->glInternalFmt, w, h, GL_FALSE)); + } else { + GL_CHECK(glTexStorage2D(gpuTexture->glTarget, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h)); } - } + break; + case TextureType::TEX3D: + CC_ASSERT(gpuTexture->glSamples <= 1); + case TextureType::TEX2D_ARRAY: + if (gpuTexture->glSamples > 1 && !gpuTexture->immutable && device->constantRegistry()->glMinorVersion >= 1) { + gpuTexture->glTarget = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; + GL_CHECK(glTexStorage3DMultisample(gpuTexture->glTarget, gpuTexture->glSamples, gpuTexture->glInternalFmt, w, h, d, GL_FALSE)); + } else { + GL_CHECK(glTexStorage3D(gpuTexture->glTarget, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h, d)); + } + break; + default: + break; + } +} - // skip multi-sampled attachment resources if we can use auto resolve - if (device->constantRegistry()->mMSRT != MSRTSupportLevel::NONE && - gpuTexture->usage == TextureUsageBit::COLOR_ATTACHMENT) { - gpuTexture->memoryless = true; +static bool useRenderBuffer(const GLES3Device *device, Format format, TextureUsage usage) { + return !device->isTextureExclusive(format) && + hasAllFlags(TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_STENCIL_ATTACHMENT, usage); +} + +void cmdFuncGLES3CreateTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) { + gpuTexture->glInternalFmt = mapGLInternalFormat(gpuTexture->format); + gpuTexture->glFormat = mapGLFormat(gpuTexture->format); + gpuTexture->glType = formatToGLType(gpuTexture->format); + gpuTexture->glSamples = static_cast(gpuTexture->samples); + + bool supportRenderBufferMS = device->constantRegistry()->mMSRT > MSRTSupportLevel::NONE; + gpuTexture->useRenderBuffer = useRenderBuffer(device, gpuTexture->format, gpuTexture->usage) && + (gpuTexture->samples <= SampleCount::X1 || supportRenderBufferMS); + + if (gpuTexture->samples > SampleCount::X1) { + // Allocate render buffer when binding a framebuffer if the MSRT extension is not present. + if (gpuTexture->useRenderBuffer && + hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED)) { + gpuTexture->glTarget = GL_RENDERBUFFER; + gpuTexture->allocateMemory = false; return; } } @@ -838,97 +886,18 @@ void cmdFuncGLES3CreateTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) return; } - if (!device->isTextureExclusive(gpuTexture->format) && (gpuTexture->glSamples > 1 || hasAllFlags(TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_STENCIL_ATTACHMENT, gpuTexture->usage))) { - switch (gpuTexture->type) { - case TextureType::TEX2D: { - gpuTexture->glTarget = GL_RENDERBUFFER; - GL_CHECK(glGenRenderbuffers(1, &gpuTexture->glRenderbuffer)); - if (gpuTexture->size > 0) { - GLuint &glRenderbuffer = device->stateCache()->glRenderbuffer; - if (gpuTexture->glRenderbuffer != glRenderbuffer) { - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, gpuTexture->glRenderbuffer)); - glRenderbuffer = gpuTexture->glRenderbuffer; - } - if (gpuTexture->glSamples > 1) { - GL_CHECK(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, gpuTexture->glSamples, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); - } else { - GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); - } - } - break; - } - default: - CC_ABORT(); - break; - } + if (gpuTexture->size == 0) { + return; + } + + if (gpuTexture->useRenderBuffer) { + gpuTexture->glTarget = GL_RENDERBUFFER; + GL_CHECK(glGenRenderbuffers(1, &gpuTexture->glRenderbuffer)); + renderBufferStorage(device, gpuTexture); } else { - switch (gpuTexture->type) { - case TextureType::TEX2D: { - gpuTexture->glTarget = GL_TEXTURE_2D; - GL_CHECK(glGenTextures(1, &gpuTexture->glTexture)); - if (gpuTexture->size > 0) { - GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; - if (gpuTexture->glTexture != glTexture) { - GL_CHECK(glBindTexture(GL_TEXTURE_2D, gpuTexture->glTexture)); - glTexture = gpuTexture->glTexture; - } - uint32_t w = gpuTexture->width; - uint32_t h = gpuTexture->height; - GL_CHECK(glTexStorage2D(GL_TEXTURE_2D, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h)); - } - break; - } - case TextureType::TEX2D_ARRAY: { - gpuTexture->glTarget = GL_TEXTURE_2D_ARRAY; - GL_CHECK(glGenTextures(1, &gpuTexture->glTexture)); - if (gpuTexture->size > 0) { - GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; - if (gpuTexture->glTexture != glTexture) { - GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, gpuTexture->glTexture)); - glTexture = gpuTexture->glTexture; - } - uint32_t w = gpuTexture->width; - uint32_t h = gpuTexture->height; - uint32_t d = gpuTexture->arrayLayer; - GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h, d)); - } - break; - } - case TextureType::TEX3D: { - gpuTexture->glTarget = GL_TEXTURE_3D; - GL_CHECK(glGenTextures(1, &gpuTexture->glTexture)); - if (gpuTexture->size > 0) { - GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; - if (gpuTexture->glTexture != glTexture) { - GL_CHECK(glBindTexture(GL_TEXTURE_3D, gpuTexture->glTexture)); - glTexture = gpuTexture->glTexture; - } - uint32_t w = gpuTexture->width; - uint32_t h = gpuTexture->height; - uint32_t d = gpuTexture->depth; - GL_CHECK(glTexStorage3D(GL_TEXTURE_3D, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h, d)); - } - break; - } - case TextureType::CUBE: { - gpuTexture->glTarget = GL_TEXTURE_CUBE_MAP; - GL_CHECK(glGenTextures(1, &gpuTexture->glTexture)); - if (gpuTexture->size > 0) { - GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; - if (gpuTexture->glTexture != glTexture) { - GL_CHECK(glBindTexture(GL_TEXTURE_CUBE_MAP, gpuTexture->glTexture)); - glTexture = gpuTexture->glTexture; - } - uint32_t w = gpuTexture->width; - uint32_t h = gpuTexture->height; - GL_CHECK(glTexStorage2D(GL_TEXTURE_CUBE_MAP, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h)); - } - break; - } - default: - CC_ABORT(); - break; - } + gpuTexture->glTarget = getTextureTarget(gpuTexture->type); + GL_CHECK(glGenTextures(1, &gpuTexture->glTexture)); + textureStorage(device, gpuTexture); } } @@ -957,36 +926,18 @@ void cmdFuncGLES3DestroyTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture } void cmdFuncGLES3ResizeTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) { - if (gpuTexture->memoryless || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) || + if (!gpuTexture->allocateMemory || + hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_NORMAL)) { return; } - if (gpuTexture->glSamples <= 1) { + if (!gpuTexture->useRenderBuffer) { // immutable by default cmdFuncGLES3DestroyTexture(device, gpuTexture); cmdFuncGLES3CreateTexture(device, gpuTexture); - } else { - switch (gpuTexture->type) { - case TextureType::TEX2D: { - if (gpuTexture->size > 0) { - GLuint &glRenderbuffer = device->stateCache()->glRenderbuffer; - if (gpuTexture->glRenderbuffer != glRenderbuffer) { - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, gpuTexture->glRenderbuffer)); - glRenderbuffer = gpuTexture->glRenderbuffer; - } - if (gpuTexture->glSamples > 1) { - GL_CHECK(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, gpuTexture->glSamples, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); - } else { - GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, gpuTexture->glInternalFmt, gpuTexture->width, gpuTexture->height)); - } - } - break; - } - default: - CC_ABORT(); - break; - } + } else if (gpuTexture->size > 0){ + renderBufferStorage(device, gpuTexture); } } @@ -1450,6 +1401,10 @@ void cmdFuncGLES3CreateRenderPass(GLES3Device * /*device*/, GLES3GPURenderPass * } for (auto &resolve : sub.resolves) { + if (resolve == INVALID_BINDING) { + gpuRenderPass->resolves.emplace_back(resolve); + continue; + } auto &index = gpuRenderPass->indices[resolve]; if (index == INVALID_BINDING) { index = static_cast(gpuRenderPass->resolves.size()); @@ -1458,6 +1413,7 @@ void cmdFuncGLES3CreateRenderPass(GLES3Device * /*device*/, GLES3GPURenderPass * } gpuRenderPass->depthStencil = sub.depthStencil; + gpuRenderPass->depthStencilResolve = sub.depthStencilResolve; } } @@ -1515,187 +1471,168 @@ void cmdFuncGLES3DestroyInputAssembler(GLES3Device *device, GLES3GPUInputAssembl gpuInputAssembler->glVAOs.clear(); } -static GLES3GPUFramebuffer::GLFramebufferInfo doCreateFramebuffer(GLES3Device *device, - const ccstd::vector &attachments, const uint32_t *colors, size_t colorCount, - const GLES3GPUTextureView *depthStencilView, - const uint32_t *resolves = nullptr, - const GLES3GPUTextureView *depthStencilResolveView = nullptr, - GLbitfield *resolveMask = nullptr) { - static ccstd::vector drawBuffers; - GLES3GPUStateCache *cache = device->stateCache(); - GLES3GPUFramebuffer::GLFramebufferInfo res; - - GL_CHECK(glGenFramebuffers(1, &res.glFramebuffer)); - if (cache->glDrawFramebuffer != res.glFramebuffer) { - GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, res.glFramebuffer)); - cache->glDrawFramebuffer = res.glFramebuffer; - } - - drawBuffers.clear(); - - auto supportLevel = device->constantRegistry()->mMSRT; - bool autoResolve = supportLevel > MSRTSupportLevel::LEVEL1 || (supportLevel != MSRTSupportLevel::NONE && colorCount <= 1); - - for (size_t j = 0; j < colorCount; ++j) { - GLES3GPUTextureView *gpuColorTextureView = attachments[colors[j]]; - GLES3GPUTextureView *gpuResolveTextureView = resolves ? attachments[resolves[j]] : nullptr; - GLES3GPUTexture *gpuColorTexture = gpuColorTextureView->gpuTexture; - GLES3GPUTexture *gpuResolveTexture = resolves ? gpuResolveTextureView->gpuTexture : nullptr; - - drawBuffers.push_back(static_cast(GL_COLOR_ATTACHMENT0 + j)); - - if (gpuResolveTexture) { - if (autoResolve) { - GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, static_cast(GL_COLOR_ATTACHMENT0 + j), - gpuResolveTexture->glTarget, gpuResolveTexture->glTexture, - gpuResolveTextureView->baseLevel, gpuColorTexture->glSamples)); +static GLES3GPUSwapchain *getSwapchainIfExists(const ccstd::vector &textureViews, const uint32_t *indices, size_t count) { + GLES3GPUSwapchain *swapchain{nullptr}; + if (indices) { + for (size_t i = 0; i < count; ++i) { + if (indices[i] == INVALID_BINDING) { continue; } - *resolveMask |= GL_COLOR_BUFFER_BIT; // fallback to blit-based manual resolve - } - if (gpuColorTexture) { - if (gpuColorTexture->glTexture) { - GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, static_cast(GL_COLOR_ATTACHMENT0 + j), - gpuColorTexture->glTarget, gpuColorTexture->glTexture, gpuColorTextureView->baseLevel)); - } else { - GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, static_cast(GL_COLOR_ATTACHMENT0 + j), - gpuColorTexture->glTarget, gpuColorTexture->glRenderbuffer)); + auto *colorTexture = textureViews[indices[i]]->gpuTexture; + if (colorTexture->swapchain) { + swapchain = colorTexture->swapchain; } } - res.width = std::min(res.width, gpuColorTexture->width); - res.height = std::min(res.height, gpuColorTexture->height); } + return swapchain; +} - GLES3GPUTexture *depthStencil = depthStencilView ? depthStencilView->gpuTexture : nullptr; - GLES3GPUTexture *depthStencilResolve = depthStencilResolveView ? depthStencilResolveView->gpuTexture : nullptr; - if (depthStencil) { - bool hasStencil = GFX_FORMAT_INFOS[static_cast(depthStencil->format)].hasStencil; - GLenum glAttachment = hasStencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; - if (depthStencil->glTexture) { - GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, depthStencil->glTarget, depthStencil->glTexture, depthStencilView->baseLevel)); - } else if (depthStencil->glRenderbuffer) { - GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, glAttachment, depthStencil->glTarget, depthStencil->glRenderbuffer)); - } - - // fallback to blit-based manual resolve - if (depthStencilResolve) *resolveMask |= hasStencil ? GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT; - res.width = std::min(res.width, depthStencil->width >> depthStencilView->baseLevel); - res.height = std::min(res.height, depthStencil->height >> depthStencilView->baseLevel); +static GLbitfield getColorBufferMask(Format format) { + GLbitfield mask = 0U; + const FormatInfo &info = GFX_FORMAT_INFOS[toNumber(format)]; + if (info.hasDepth || info.hasStencil) { + if (info.hasDepth) mask |= GL_DEPTH_BUFFER_BIT; + if (info.hasStencil) mask |= GL_STENCIL_BUFFER_BIT; + } else { + mask = GL_COLOR_BUFFER_BIT; } + return mask; +} - // register to framebuffer caches - if (colorCount == 1) device->framebufferCacheMap()->registerExternal(res.glFramebuffer, attachments[colors[0]]->gpuTexture, 0); - if (depthStencil) device->framebufferCacheMap()->registerExternal(res.glFramebuffer, depthStencilView->gpuTexture, 0); +static void doResolve(GLES3Device *device, GLES3GPUFramebuffer *gpuFbo) { + device->context()->makeCurrent(gpuFbo->resolveFramebuffer.swapchain, gpuFbo->framebuffer.swapchain); + auto *cache = device->stateCache(); + auto width = gpuFbo->width; + auto height = gpuFbo->height; - GL_CHECK(glDrawBuffers(utils::toUint(drawBuffers.size()), drawBuffers.data())); + if (cache->glReadFramebuffer != gpuFbo->framebuffer.handle) { + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, gpuFbo->framebuffer.handle)); + cache->glReadFramebuffer = gpuFbo->framebuffer.handle; + } - GLenum status; - GL_CHECK(status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); - if (status != GL_FRAMEBUFFER_COMPLETE) { - switch (status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED"); - break; - default: - CC_LOG_ERROR("checkFramebufferStatus() - %x", status); - break; - } + if (cache->glDrawFramebuffer != gpuFbo->resolveFramebuffer.handle) { + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpuFbo->resolveFramebuffer.handle)); + cache->glDrawFramebuffer = gpuFbo->resolveFramebuffer.handle; } - return res; -} + gpuFbo->resolveFramebuffer.processLoad(GL_DRAW_FRAMEBUFFER); -static GLES3GPUSwapchain *getSwapchainIfExists(const ccstd::vector &textureViews, const uint32_t *indices, size_t count) { - GLES3GPUSwapchain *swapchain{nullptr}; - if (indices) { - size_t offscreenCount{0}; - for (size_t i = 0; i < count; ++i) { - auto *colorTexture = textureViews[indices[i]]->gpuTexture; - if (colorTexture->swapchain) { - swapchain = colorTexture->swapchain; - } else { - ++offscreenCount; + if (!gpuFbo->colorBlitPairs.empty()) { + auto resolveColorNum = gpuFbo->resolveFramebuffer.colors.size(); + std::vector drawBuffers(resolveColorNum, GL_NONE); + for (auto &[src, dst] : gpuFbo->colorBlitPairs) { + drawBuffers[dst] = GL_COLOR_ATTACHMENT0 + dst; + GL_CHECK(glReadBuffer(GL_COLOR_ATTACHMENT0 + src)); + if (gpuFbo->resolveFramebuffer.handle != 0) { + GL_CHECK(glDrawBuffers(resolveColorNum, drawBuffers.data())); } + + GL_CHECK(glBlitFramebuffer( + 0, 0, width, height, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, GL_NEAREST)); + drawBuffers[dst] = GL_NONE; } - CC_ASSERT(!offscreenCount || offscreenCount == count); } - return swapchain; + if (gpuFbo->dsResolveMask != 0 && gpuFbo->resolveFramebuffer.handle != 0) { + GL_CHECK(glBlitFramebuffer( + 0, 0, width, height, + 0, 0, width, height, + gpuFbo->dsResolveMask, GL_NEAREST)); + } + + gpuFbo->framebuffer.processStore(GL_READ_FRAMEBUFFER); + gpuFbo->resolveFramebuffer.processStore(GL_DRAW_FRAMEBUFFER); } -static void doCreateFramebufferInstance(GLES3Device *device, GLES3GPUFramebuffer *gpuFBO, const ccstd::vector &colors, - uint32_t depthStencil, GLES3GPUFramebuffer::Framebuffer *outFBO, - const uint32_t *resolves = nullptr, uint32_t depthStencilResolve = INVALID_BINDING) { - GLES3GPUSwapchain *swapchain{getSwapchainIfExists(gpuFBO->gpuColorViews, colors.data(), colors.size())}; - if (!swapchain) { - const GLES3GPUTextureView *depthStencilTextureView = nullptr; - if (depthStencil != INVALID_BINDING) { - depthStencilTextureView = depthStencil < gpuFBO->gpuColorViews.size() - ? gpuFBO->gpuColorViews[depthStencil] - : gpuFBO->gpuDepthStencilView; - } - const GLES3GPUTextureView *depthStencilResolveTextureView = nullptr; - if (depthStencilResolve != INVALID_BINDING) { - depthStencilResolveTextureView = depthStencilResolve < gpuFBO->gpuColorViews.size() - ? gpuFBO->gpuColorViews[depthStencilResolve] - : gpuFBO->gpuDepthStencilView; - } - - outFBO->framebuffer.initialize(doCreateFramebuffer(device, gpuFBO->gpuColorViews, colors.data(), utils::toUint(colors.size()), - depthStencilTextureView, resolves, depthStencilResolveTextureView, &outFBO->resolveMask)); - if (outFBO->resolveMask) { - size_t resolveCount = outFBO->resolveMask & GL_COLOR_BUFFER_BIT ? utils::toUint(colors.size()) : 0U; - GLES3GPUSwapchain *resolveSwapchain{getSwapchainIfExists(gpuFBO->gpuColorViews, resolves, resolveCount)}; - if (!resolveSwapchain) { - outFBO->resolveFramebuffer.initialize(doCreateFramebuffer(device, gpuFBO->gpuColorViews, resolves, resolveCount, depthStencilResolveTextureView)); +void cmdFuncGLES3CreateFramebuffer(GLES3Device *device, GLES3GPUFramebuffer *gpuFBO) { + const auto *renderPass = gpuFBO->gpuRenderPass; + const auto &colors = renderPass->colors; + const auto &resolves = renderPass->resolves; + const auto &indices = renderPass->indices; + const auto depthStencil = renderPass->depthStencil; + const auto depthStencilResolve = renderPass->depthStencilResolve; + + gpuFBO->framebuffer.initialize(getSwapchainIfExists(gpuFBO->gpuColorViews, colors.data(), colors.size())); + gpuFBO->resolveFramebuffer.initialize(getSwapchainIfExists(gpuFBO->gpuColorViews, resolves.data(), resolves.size())); + + auto supportLevel = device->constantRegistry()->mMSRT; + /* + * LEVEL0 does ont support on-chip resolve + * LEVEL1 only support COLOR_ATTACHMENT0 + * LEVEL2 support COLOR_ATTACHMENT(i) + DEPTH_STENCIL + */ + uint32_t supportCount = supportLevel > MSRTSupportLevel::LEVEL1 ? 255 : static_cast(supportLevel); + constexpr bool useDsResolve = true; + + uint32_t resolveColorIndex = 0; + for (uint32_t i = 0; i < colors.size(); ++i) { + const auto &attachmentIndex = colors[i]; + const auto &colorIndex = indices[attachmentIndex]; + const auto &resolveIndex = resolves.empty() ? INVALID_BINDING : resolves[attachmentIndex]; + + const auto &desc = renderPass->colorAttachments[attachmentIndex]; + const auto *view = gpuFBO->gpuColorViews[attachmentIndex]; + CC_ASSERT(view != nullptr); + + // need to resolve + if (view->gpuTexture->glSamples != 1 && resolveIndex != INVALID_BINDING) { + const auto &resolveDesc = renderPass->colorAttachments[resolveIndex]; + const auto *resolveView = gpuFBO->gpuColorViews[resolveIndex]; + CC_ASSERT(resolveView != nullptr); + bool lazilyAllocated = hasFlag(view->gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED); + + if (lazilyAllocated && // MS attachment should be memoryless + resolveView->gpuTexture->swapchain == nullptr && // not back buffer + i < supportCount) { // extension limit + gpuFBO->framebuffer.bindColorMultiSample(resolveView, colorIndex, view->gpuTexture->glSamples, resolveDesc); } else { - outFBO->resolveFramebuffer.initialize(resolveSwapchain); + // implicit MS not supported, fallback to MS Renderbuffer + gpuFBO->colorBlitPairs.emplace_back(colorIndex, resolveColorIndex); + gpuFBO->framebuffer.bindColor(view, colorIndex, desc); + gpuFBO->resolveFramebuffer.bindColor(resolveView, resolveColorIndex++, resolveDesc); } + continue; } - } else { - outFBO->framebuffer.initialize(swapchain); + gpuFBO->framebuffer.bindColor(view, colorIndex, desc); } -} -void cmdFuncGLES3CreateFramebuffer(GLES3Device *device, GLES3GPUFramebuffer *gpuFBO) { - const auto &colors = gpuFBO->gpuRenderPass->colors; - const auto &resolves = gpuFBO->gpuRenderPass->resolves; - const auto &depthStencil = gpuFBO->gpuRenderPass->depthStencil; + if (depthStencil != INVALID_BINDING) { + const auto &desc = renderPass->depthStencilAttachment; + const auto *view = gpuFBO->gpuDepthStencilView; + CC_ASSERT(view != nullptr); - doCreateFramebufferInstance(device, gpuFBO, colors, depthStencil, &gpuFBO->frameBuffer, resolves.empty() ? nullptr : resolves.data()); -} + if (view->gpuTexture->glSamples != 1 && depthStencilResolve != INVALID_BINDING) { + const auto &resolveDesc = renderPass->depthStencilResolveAttachment; + const auto *resolveView = gpuFBO->gpuDepthStencilResolveView; + bool lazilyAllocated = hasFlag(view->gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED); -void GLES3GPUFramebuffer::GLFramebuffer::destroy(GLES3GPUStateCache *cache, GLES3GPUFramebufferCacheMap *framebufferCacheMap) { - if (swapchain) { - swapchain = nullptr; - } else { - if (cache->glDrawFramebuffer == _glFramebuffer) { - GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); - cache->glDrawFramebuffer = 0; + if (lazilyAllocated && // MS attachment should be memoryless + resolveView->gpuTexture->swapchain == nullptr && // not back buffer + supportCount > 1 && // extension limit + useDsResolve) { // enable ds resolve + gpuFBO->framebuffer.bindDepthStencilMultiSample(resolveView, view->gpuTexture->glSamples, resolveDesc); + } else { + // implicit MS not supported, fallback to MS Renderbuffer + gpuFBO->dsResolveMask = getColorBufferMask(desc.format); + gpuFBO->framebuffer.bindDepthStencil(view, desc); + gpuFBO->resolveFramebuffer.bindDepthStencil(resolveView, resolveDesc); + } + } else { + gpuFBO->framebuffer.bindDepthStencil(view, desc); } - GL_CHECK(glDeleteFramebuffers(1, &_glFramebuffer)); - framebufferCacheMap->unregisterExternal(_glFramebuffer); - _glFramebuffer = 0U; } + + gpuFBO->framebuffer.finalize(device->stateCache()); + gpuFBO->resolveFramebuffer.finalize(device->stateCache()); } void cmdFuncGLES3DestroyFramebuffer(GLES3Device *device, GLES3GPUFramebuffer *gpuFBO) { auto *cache = device->stateCache(); auto *framebufferCacheMap = device->framebufferCacheMap(); - gpuFBO->frameBuffer.framebuffer.destroy(cache, framebufferCacheMap); - gpuFBO->frameBuffer.resolveFramebuffer.destroy(cache, framebufferCacheMap); + gpuFBO->framebuffer.destroy(cache, framebufferCacheMap); + gpuFBO->resolveFramebuffer.destroy(cache, framebufferCacheMap); } void completeBarrier(GLES3GPUGeneralBarrier *barrier) { @@ -1857,7 +1794,6 @@ void cmdFuncGLES3Query(GLES3Device * /*device*/, GLES3QueryPool *queryPool, GLES void cmdFuncGLES3BeginRenderPass(GLES3Device *device, GLES3GPURenderPass *gpuRenderPass, GLES3GPUFramebuffer *gpuFramebuffer, const Rect *renderArea, const Color *clearColors, float clearDepth, uint32_t clearStencil) { - ccstd::vector invalidAttachments; GLES3GPUStateCache *cache = device->stateCache(); GLES3ObjectCache &gfxStateCache = cache->gfxStateCache; gfxStateCache.subpassIdx = 0; @@ -1869,14 +1805,18 @@ void cmdFuncGLES3BeginRenderPass(GLES3Device *device, GLES3GPURenderPass *gpuRen gfxStateCache.clearStencil = clearStencil; if (gpuFramebuffer && gpuRenderPass) { - auto &instance = gpuFramebuffer->frameBuffer; + auto &framebuffer = gpuFramebuffer->framebuffer; + auto &resolveFramebuffer = gpuFramebuffer->resolveFramebuffer; + if (gpuFramebuffer->resolveFramebuffer.isActive()) { + device->context()->makeCurrent(resolveFramebuffer.swapchain, framebuffer.swapchain); + } else { + device->context()->makeCurrent(framebuffer.swapchain); + } - GLuint glFramebuffer = instance.framebuffer.getFramebuffer(); - device->context()->makeCurrent(instance.framebuffer.swapchain, instance.framebuffer.swapchain); - if (cache->glDrawFramebuffer != glFramebuffer) { - GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glFramebuffer)); - cache->glDrawFramebuffer = glFramebuffer; + if (cache->glDrawFramebuffer != framebuffer.handle) { + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle)); + cache->glDrawFramebuffer = framebuffer.handle; } if (cache->viewport.left != renderArea->x || @@ -1896,38 +1836,27 @@ void cmdFuncGLES3BeginRenderPass(GLES3Device *device, GLES3GPURenderPass *gpuRen } GLbitfield glClears = 0; - invalidAttachments.clear(); - float fColors[4]{}; bool maskSet = false; auto performLoadOp = [&](uint32_t attachmentIndex, uint32_t glAttachmentIndex) { const ColorAttachment &colorAttachment = gpuRenderPass->colorAttachments[attachmentIndex]; - if (colorAttachment.format != Format::UNKNOWN) { - switch (colorAttachment.loadOp) { - case LoadOp::LOAD: break; // GL default behaviour - case LoadOp::CLEAR: { - if (!maskSet && cache->bs.targets[0].blendColorMask != ColorMask::ALL) { - GL_CHECK(glColorMask(true, true, true, true)); - maskSet = true; - } + if (colorAttachment.format != Format::UNKNOWN && colorAttachment.loadOp == LoadOp::CLEAR) { + if (!maskSet && cache->bs.targets[0].blendColorMask != ColorMask::ALL) { + GL_CHECK(glColorMask(true, true, true, true)); + maskSet = true; + } - const Color &color = clearColors[attachmentIndex]; - if (glFramebuffer) { - fColors[0] = color.x; - fColors[1] = color.y; - fColors[2] = color.z; - fColors[3] = color.w; - GL_CHECK(glClearBufferfv(GL_COLOR, glAttachmentIndex, fColors)); - } else { - GL_CHECK(glClearColor(color.x, color.y, color.z, color.w)); - glClears |= GL_COLOR_BUFFER_BIT; - } - } break; - case LoadOp::DISCARD: - // invalidate fbo - invalidAttachments.push_back(glFramebuffer ? GL_COLOR_ATTACHMENT0 + glAttachmentIndex : GL_COLOR); - break; + const Color &color = clearColors[attachmentIndex]; + if (framebuffer.handle) { + fColors[0] = color.x; + fColors[1] = color.y; + fColors[2] = color.z; + fColors[3] = color.w; + GL_CHECK(glClearBufferfv(GL_COLOR, glAttachmentIndex, fColors)); + } else { + GL_CHECK(glClearColor(color.x, color.y, color.z, color.w)); + glClears |= GL_COLOR_BUFFER_BIT; } } }; @@ -1941,43 +1870,25 @@ void cmdFuncGLES3BeginRenderPass(GLES3Device *device, GLES3GPURenderPass *gpuRen depthLoadOp = stencilLoadOp = gpuRenderPass->colorAttachments[attachmentIndex].loadOp; hasStencils = GFX_FORMAT_INFOS[toNumber(gpuRenderPass->colorAttachments[attachmentIndex].format)].hasStencil; } - switch (gpuRenderPass->depthStencilAttachment.depthLoadOp) { - case LoadOp::LOAD: break; // GL default behaviour - case LoadOp::CLEAR: - if (!cache->dss.depthWrite) { - GL_CHECK(glDepthMask(true)); - } - GL_CHECK(glClearDepthf(clearDepth)); - glClears |= GL_DEPTH_BUFFER_BIT; - break; - case LoadOp::DISCARD: - invalidAttachments.push_back(glFramebuffer ? GL_DEPTH_ATTACHMENT : GL_DEPTH); - break; + if (gpuRenderPass->depthStencilAttachment.depthLoadOp == LoadOp::CLEAR) { + if (!cache->dss.depthWrite) { + GL_CHECK(glDepthMask(true)); + } + GL_CHECK(glClearDepthf(clearDepth)); + glClears |= GL_DEPTH_BUFFER_BIT; } - if (hasStencils) { - switch (gpuRenderPass->depthStencilAttachment.depthLoadOp) { - case LoadOp::LOAD: break; // GL default behaviour - case LoadOp::CLEAR: { - if (!cache->dss.stencilWriteMaskFront) { - GL_CHECK(glStencilMaskSeparate(GL_FRONT, 0xffffffff)); - } - if (!cache->dss.stencilWriteMaskBack) { - GL_CHECK(glStencilMaskSeparate(GL_BACK, 0xffffffff)); - } - GL_CHECK(glClearStencil(clearStencil)); - glClears |= GL_STENCIL_BUFFER_BIT; - } break; - case LoadOp::DISCARD: - invalidAttachments.push_back(glFramebuffer ? GL_STENCIL_ATTACHMENT : GL_STENCIL); - break; + if (hasStencils && gpuRenderPass->depthStencilAttachment.depthLoadOp == LoadOp::CLEAR) { + if (!cache->dss.stencilWriteMaskFront) { + GL_CHECK(glStencilMaskSeparate(GL_FRONT, 0xffffffff)); + } + if (!cache->dss.stencilWriteMaskBack) { + GL_CHECK(glStencilMaskSeparate(GL_BACK, 0xffffffff)); } + GL_CHECK(glClearStencil(clearStencil)); + glClears |= GL_STENCIL_BUFFER_BIT; } } - if (!invalidAttachments.empty()) { - GL_CHECK(glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, utils::toUint(invalidAttachments.size()), invalidAttachments.data())); - } - if (glClears) { GL_CHECK(glClear(glClears)); } @@ -2011,6 +1922,8 @@ void cmdFuncGLES3BeginRenderPass(GLES3Device *device, GLES3GPURenderPass *gpuRen performLoadOp(i, indices[i]); } performDepthStencilLoadOp(gpuRenderPass->depthStencil); + + framebuffer.processLoad(GL_DRAW_FRAMEBUFFER); } } @@ -2032,113 +1945,14 @@ void cmdFuncGLES3EndRenderPass(GLES3Device *device) { GLES3GPUStateCache *cache = device->stateCache(); GLES3ObjectCache &gfxStateCache = cache->gfxStateCache; - GLES3GPURenderPass *gpuRenderPass = gfxStateCache.gpuRenderPass; GLES3GPUFramebuffer *gpuFramebuffer = gfxStateCache.gpuFramebuffer; - const auto &instance = gpuFramebuffer->frameBuffer; - const SubpassInfo &subpass = gpuRenderPass->subpasses[gfxStateCache.subpassIdx]; - - GLuint glFramebuffer = instance.framebuffer.getFramebuffer(); - GLuint glResolveFramebuffer = instance.resolveFramebuffer.getFramebuffer(); - GLenum invalidateTarget = GL_DRAW_FRAMEBUFFER; - - auto performStoreOp = [&](uint32_t attachmentIndex, uint32_t glAttachmentIndex) { - const ColorAttachment &colorAttachment = gpuRenderPass->colorAttachments[attachmentIndex]; - if (colorAttachment.format != Format::UNKNOWN) { - switch (colorAttachment.storeOp) { - case StoreOp::STORE: break; - case StoreOp::DISCARD: - // invalidate fbo - invalidAttachments.push_back(glFramebuffer ? GL_COLOR_ATTACHMENT0 + glAttachmentIndex : GL_COLOR); - break; - } - } - }; - - auto performDepthStencilStoreOp = [&](uint32_t attachmentIndex) { - if (attachmentIndex != INVALID_BINDING) { - StoreOp depthStoreOp = gpuRenderPass->depthStencilAttachment.depthStoreOp; - StoreOp stencilStoreOp = gpuRenderPass->depthStencilAttachment.stencilStoreOp; - bool hasStencils = GFX_FORMAT_INFOS[toNumber(gpuRenderPass->depthStencilAttachment.format)].hasStencil; - if (attachmentIndex < gpuRenderPass->colorAttachments.size()) { - depthStoreOp = stencilStoreOp = gpuRenderPass->colorAttachments[attachmentIndex].storeOp; - hasStencils = GFX_FORMAT_INFOS[toNumber(gpuRenderPass->colorAttachments[attachmentIndex].format)].hasStencil; - } - - switch (gpuRenderPass->depthStencilAttachment.depthStoreOp) { - case StoreOp::STORE: break; - case StoreOp::DISCARD: - invalidAttachments.push_back(glFramebuffer ? GL_DEPTH_ATTACHMENT : GL_DEPTH); - break; - } - if (hasStencils) { - switch (gpuRenderPass->depthStencilAttachment.stencilStoreOp) { - case StoreOp::STORE: break; - case StoreOp::DISCARD: - invalidAttachments.push_back(glFramebuffer ? GL_STENCIL_ATTACHMENT : GL_STENCIL); - break; - } - } - } - - if (!invalidAttachments.empty()) { - GL_CHECK(glInvalidateFramebuffer(invalidateTarget, utils::toUint(invalidAttachments.size()), invalidAttachments.data())); - } - }; - - if (instance.resolveMask) { - device->context()->makeCurrent(instance.resolveFramebuffer.swapchain, instance.framebuffer.swapchain); - - if (cache->glReadFramebuffer != glFramebuffer) { - GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, glFramebuffer)); - cache->glReadFramebuffer = glFramebuffer; - } - - if (cache->glDrawFramebuffer != glResolveFramebuffer) { - GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glResolveFramebuffer)); - cache->glDrawFramebuffer = glResolveFramebuffer; - } - - if (instance.resolveMask & GL_COLOR_BUFFER_BIT) { - for (uint32_t i = 0; i < subpass.colors.size(); ++i) { - auto attachment = static_cast(GL_COLOR_ATTACHMENT0 + i); - GL_CHECK(glReadBuffer(attachment)); - GL_CHECK(glDrawBuffers(1, &attachment)); - - GLES3GPUTexture *srcTex = gpuFramebuffer->gpuColorViews[subpass.colors[i]]->gpuTexture; - GLES3GPUTexture *dstTex = gpuFramebuffer->gpuColorViews[subpass.resolves[i]]->gpuTexture; - ensureScissorRect(cache, 0, 0, dstTex->width, dstTex->height); - GL_CHECK(glBlitFramebuffer( - 0, 0, srcTex->width, srcTex->height, - 0, 0, dstTex->width, dstTex->height, - GL_COLOR_BUFFER_BIT, GL_NEAREST)); - } - } - - if (instance.resolveMask & GL_DEPTH_BUFFER_BIT) { - GLES3GPUTexture *srcTex = subpass.depthStencil < gpuFramebuffer->gpuColorViews.size() - ? gpuFramebuffer->gpuColorViews[subpass.depthStencil]->gpuTexture - : gpuFramebuffer->gpuDepthStencilView->gpuTexture; - GLES3GPUTexture *dstTex = subpass.depthStencilResolve < gpuFramebuffer->gpuColorViews.size() - ? gpuFramebuffer->gpuColorViews[subpass.depthStencilResolve]->gpuTexture - : gpuFramebuffer->gpuDepthStencilView->gpuTexture; - - ensureScissorRect(cache, 0, 0, dstTex->width, dstTex->height); - GL_CHECK(glBlitFramebuffer( - 0, 0, srcTex->width, srcTex->height, - 0, 0, dstTex->width, dstTex->height, - instance.resolveMask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT), GL_NEAREST)); - } - - invalidateTarget = GL_READ_FRAMEBUFFER; + if (gpuFramebuffer->resolveFramebuffer.isActive()) { + doResolve(device, gpuFramebuffer); + } else { + gpuFramebuffer->framebuffer.processStore(GL_DRAW_FRAMEBUFFER); } - const auto &attachments = gpuRenderPass->colorAttachments; - const auto &indices = gpuRenderPass->indices; - for (uint32_t i = 0; i < attachments.size(); ++i) { - performStoreOp(i, indices[i]); - } - performDepthStencilStoreOp(gpuRenderPass->depthStencil); // if (device->constantRegistry()->mFBF == FBFSupportLevel::NON_COHERENT_EXT) { // GL_CHECK(glFramebufferFetchBarrierEXT()); // } else if (device->constantRegistry()->mFBF == FBFSupportLevel::NON_COHERENT_QCOM) { @@ -2363,6 +2177,10 @@ void cmdFuncGLES3BindState(GLES3Device *device, GLES3GPUPipelineState *gpuPipeli const GLES3GPUUniformBuffer &glBuffer = gpuPipelineState->gpuShader->glBuffers[j]; const GLES3GPUDescriptorSet *gpuDescriptorSet = gpuDescriptorSets[glBuffer.set]; + if (gpuDescriptorSet == nullptr) { + continue; + } + const uint32_t descriptorIndex = gpuDescriptorSet->descriptorIndices->at(glBuffer.binding); const GLES3GPUDescriptor &gpuDescriptor = gpuDescriptorSet->gpuDescriptors[descriptorIndex]; @@ -2818,7 +2636,7 @@ uint8_t *funcGLES3PixelBufferPick(const uint8_t *buffer, Format format, uint32_t } void cmdFuncGLES3CopyBuffersToTexture(GLES3Device *device, const uint8_t *const *buffers, GLES3GPUTexture *gpuTexture, const BufferTextureCopy *regions, uint32_t count) { - if (gpuTexture->memoryless) return; + if (!gpuTexture->allocateMemory) return; GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; if (glTexture != gpuTexture->glTexture) { @@ -3066,15 +2884,7 @@ void cmdFuncGLES3BlitTexture(GLES3Device *device, GLES3GPUTexture *gpuTextureSrc const TextureBlit *regions, uint32_t count, Filter filter) { GLES3GPUStateCache *cache = device->stateCache(); - GLbitfield mask = 0U; - const FormatInfo &info = GFX_FORMAT_INFOS[toNumber(gpuTextureSrc->format)]; - if (info.hasDepth || info.hasStencil) { - if (info.hasDepth) mask |= GL_DEPTH_BUFFER_BIT; - if (info.hasStencil) mask |= GL_STENCIL_BUFFER_BIT; - } else { - mask = GL_COLOR_BUFFER_BIT; - } - + GLbitfield mask = getColorBufferMask(gpuTextureSrc->format); for (uint32_t i = 0U; i < count; ++i) { const TextureBlit ®ion = regions[i]; @@ -3185,6 +2995,189 @@ void cmdFuncGLES3ExecuteCmds(GLES3Device *device, GLES3CmdPackage *cmdPackage) { } } +void GLES3GPUFramebufferObject::initialize(GLES3GPUSwapchain *swc) { + swapchain = swc; +} + +void GLES3GPUFramebufferObject::bindColor(const GLES3GPUTextureView *texture, uint32_t colorIndex, const ColorAttachment &attachment) { + bindColorMultiSample(texture, colorIndex, 1, attachment); +} + +void GLES3GPUFramebufferObject::bindColorMultiSample(const GLES3GPUTextureView *texture, uint32_t colorIndex, GLint samples, const ColorAttachment &attachment) { + if (colorIndex >= colors.size()) { + colors.resize(colorIndex + 1); + } + bool isDefaultFb = swapchain != nullptr; + + if (attachment.loadOp == LoadOp::DISCARD) { + loadInvalidates.emplace_back(isDefaultFb ? GL_COLOR : GL_COLOR_ATTACHMENT0 + colorIndex); + } + if (attachment.storeOp == StoreOp::DISCARD) { + storeInvalidates.emplace_back(isDefaultFb ? GL_COLOR : GL_COLOR_ATTACHMENT0 + colorIndex); + } + colors[colorIndex] = {texture, samples}; +} + +void GLES3GPUFramebufferObject::bindDepthStencil(const GLES3GPUTextureView *texture, const DepthStencilAttachment &attachment) { + bindDepthStencilMultiSample(texture, 1, attachment); +} + +void GLES3GPUFramebufferObject::bindDepthStencilMultiSample(const GLES3GPUTextureView *texture, GLint samples, const DepthStencilAttachment &attachment) { + const FormatInfo &info = GFX_FORMAT_INFOS[toNumber(texture->gpuTexture->format)]; + + bool isDefaultFb = swapchain != nullptr; + bool hasDepth = info.hasDepth; + bool hasStencil = info.hasStencil; + + dsAttachment = hasDepth && hasStencil ? GL_DEPTH_STENCIL_ATTACHMENT : + hasDepth ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT; + + if (hasDepth) { + auto att = isDefaultFb ? GL_DEPTH : GL_DEPTH_ATTACHMENT; + if (attachment.depthLoadOp == LoadOp::DISCARD) { + loadInvalidates.emplace_back(att); + } + if (attachment.depthStoreOp == StoreOp::DISCARD) { + storeInvalidates.emplace_back(att); + } + } + if (hasStencil) { + auto att = isDefaultFb ? GL_STENCIL : GL_STENCIL_ATTACHMENT; + if (attachment.stencilLoadOp == LoadOp::DISCARD) { + loadInvalidates.emplace_back(att); + } + if (attachment.stencilStoreOp == StoreOp::DISCARD) { + storeInvalidates.emplace_back(att); + } + } + + depthStencil.first = texture; + depthStencil.second = samples; +} + +bool GLES3GPUFramebufferObject::isActive() const { + return swapchain != nullptr || (handle != 0); +} + +void GLES3GPUFramebufferObject::processLoad(GLenum target) { + if (!loadInvalidates.empty()) { + GL_CHECK(glInvalidateFramebuffer(target, utils::toUint(loadInvalidates.size()), loadInvalidates.data())); + } +} + +void GLES3GPUFramebufferObject::processStore(GLenum target) { + if (!storeInvalidates.empty()) { + GL_CHECK(glInvalidateFramebuffer(target, utils::toUint(storeInvalidates.size()), storeInvalidates.data())); + } +} + +void GLES3GPUFramebufferObject::finalize(GLES3GPUStateCache *cache) { + if (swapchain != nullptr) { + return; + } + + if (colors.empty() && dsAttachment == GL_NONE) { + return; + } + + GL_CHECK(glGenFramebuffers(1, &handle)); + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, handle)); + cache->glDrawFramebuffer = handle; + + ccstd::vector drawBuffers(colors.size(), GL_NONE); + for (uint32_t i = 0; i < colors.size(); ++i) { + const auto &[view, samples] = colors[i]; + auto att = static_cast(GL_COLOR_ATTACHMENT0 + i); + drawBuffers[i] =att; + + auto *texture = view->gpuTexture; + if (samples != 1) { + CC_ASSERT(view->gpuTexture->glTexture != 0); + GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, + att, + GL_TEXTURE_2D, + texture->glTexture, + view->baseLevel, + static_cast(samples))); + continue; + } + + if (texture->useRenderBuffer) { + if (view->gpuTexture->glRenderbuffer == 0) { + GL_CHECK(glGenRenderbuffers(1, &view->gpuTexture->glRenderbuffer)); + renderBufferStorage(GLES3Device::getInstance(), texture); + } + GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, att, texture->glTarget, texture->glRenderbuffer)); + } else { + GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, att, texture->glTarget, texture->glTexture, view->baseLevel)); + } + } + + if (depthStencil.first != nullptr) { + const auto &[view, samples] = depthStencil; + + auto *texture = view->gpuTexture; + if (samples != 1) { + CC_ASSERT(view->gpuTexture->glTexture != 0); + GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, + dsAttachment, + texture->glTexture, + view->gpuTexture->glTexture, + view->baseLevel, + static_cast(samples))); + } else { + if (texture->useRenderBuffer) { + GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glRenderbuffer)); + } else { + GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glTexture, view->baseLevel)); + } + } + } + + if (!drawBuffers.empty()) { + GL_CHECK(glDrawBuffers(drawBuffers.size(), drawBuffers.data())); + } + + GLenum status; + GL_CHECK(status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); + if (status != GL_FRAMEBUFFER_COMPLETE) { + switch (status) { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + CC_LOG_ERROR("checkFramebufferStatus() - FRAMEBUFFER_UNSUPPORTED"); + break; + default: + CC_LOG_ERROR("checkFramebufferStatus() - %x", status); + break; + } + } +} + +void GLES3GPUFramebufferObject::destroy(GLES3GPUStateCache *cache, GLES3GPUFramebufferCacheMap *framebufferCacheMap) { + if (swapchain) { + swapchain = nullptr; + } else { + if (cache->glDrawFramebuffer == handle) { + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); + cache->glDrawFramebuffer = 0; + } + GL_CHECK(glDeleteFramebuffers(1, &handle)); + framebufferCacheMap->unregisterExternal(handle); + handle = 0U; + } +} + void GLES3GPUFramebufferHub::update(GLES3GPUTexture *texture) { auto &pool = _framebuffers[texture]; for (auto *framebuffer : pool) { @@ -3193,5 +3186,16 @@ void GLES3GPUFramebufferHub::update(GLES3GPUTexture *texture) { } } +GLint cmdFuncGLES3GetMaxSampleCount(const GLES3Device *device, Format format, TextureUsage usage, TextureFlags flags) { + std::ignore = flags; + + auto internalFormat = mapGLInternalFormat(format); + auto target = useRenderBuffer(device, format, usage) ? GL_RENDERBUFFER : GL_TEXTURE_2D_MULTISAMPLE; + + GLint maxSamples = 1; + GL_CHECK(glGetInternalformativ(target, internalFormat, GL_SAMPLES, 1, &maxSamples)); + return maxSamples; +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.h b/native/cocos/renderer/gfx-gles3/GLES3Commands.h index 7108e4ecee1..c9d612550de 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.h +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.h @@ -312,5 +312,7 @@ void cmdFuncGLES3Dispatch(GLES3Device *device, const GLES3GPUDispatchInfo &info) void cmdFuncGLES3MemoryBarrier(GLES3Device *device, GLbitfield barriers, GLbitfield barriersByRegion); +GLint cmdFuncGLES3GetMaxSampleCount(const GLES3Device *device, Format format, TextureUsage usage, TextureFlags flags); + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-gles3/GLES3Device.cpp b/native/cocos/renderer/gfx-gles3/GLES3Device.cpp index c8de3ad8f35..79bc6937af8 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Device.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Device.cpp @@ -121,7 +121,6 @@ bool GLES3Device::doInit(const DeviceInfo & /*info*/) { ccstd::string fbfLevelStr = "NONE"; // PVRVFrame has issues on their support -//#if CC_PLATFORM != CC_PLATFORM_WINDOWS if (checkExtension("framebuffer_fetch")) { ccstd::string nonCoherent = "framebuffer_fetch_non"; @@ -153,17 +152,20 @@ bool GLES3Device::doInit(const DeviceInfo & /*info*/) { _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = true; fbfLevelStr += "_DEPTH_STENCIL"; } -//#endif + ccstd::string msaaLevelStr = "NONE"; #if CC_PLATFORM != CC_PLATFORM_WINDOWS || ALLOW_MULTISAMPLED_RENDER_TO_TEXTURE_ON_DESKTOP if (checkExtension("multisampled_render_to_texture")) { + msaaLevelStr = "MSRT1"; if (checkExtension("multisampled_render_to_texture2")) { _gpuConstantRegistry->mMSRT = MSRTSupportLevel::LEVEL2; + msaaLevelStr = "MSRT2"; } else { _gpuConstantRegistry->mMSRT = MSRTSupportLevel::LEVEL1; } } #endif + _features[toNumber(Feature::MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL)] = true; ccstd::string compressedFmts; @@ -242,6 +244,7 @@ bool GLES3Device::doInit(const DeviceInfo & /*info*/) { CC_LOG_INFO("VERSION: %s", _version.c_str()); CC_LOG_INFO("COMPRESSED_FORMATS: %s", compressedFmts.c_str()); CC_LOG_INFO("FRAMEBUFFER_FETCH: %s", fbfLevelStr.c_str()); + CC_LOG_INFO("MULTI_SAMPLE_RENDER_TO_TEXTURE: %s", msaaLevelStr.c_str()); if (_xr) { _xr->initializeGLESData(pfnGLES3wLoadProc(), GLES3Device::getInstance()->context()); @@ -610,5 +613,9 @@ void GLES3Device::getQueryPoolResults(QueryPool *queryPool) { cmdBuff->getQueryPoolResults(queryPool); } +SampleCount GLES3Device::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + return static_cast(cmdFuncGLES3GetMaxSampleCount(this, format, usage, flags)); +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-gles3/GLES3Device.h b/native/cocos/renderer/gfx-gles3/GLES3Device.h index 5eed7ca400f..cba5ba99a0c 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Device.h +++ b/native/cocos/renderer/gfx-gles3/GLES3Device.h @@ -95,8 +95,8 @@ class CC_GLES3_API GLES3Device final : public Device { return _stagingBuffer; } - inline bool isTextureExclusive(const Format &format) { return _textureExclusive[static_cast(format)]; }; - + inline bool isTextureExclusive(const Format &format) const { return _textureExclusive[static_cast(format)]; }; + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; protected: static GLES3Device *instance; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.cpp index 0eb96c3b3c5..1b4b8e0f19f 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.cpp @@ -41,10 +41,25 @@ GLES3Framebuffer::~GLES3Framebuffer() { destroy(); } +void GLES3Framebuffer::updateExtent() { + if (!_colorTextures.empty()) { + const auto *tex = _colorTextures[0]; + _gpuFBO->width = tex->getWidth(); + _gpuFBO->height = tex->getHeight(); + return; + } + if (_depthStencilTexture != nullptr) { + _gpuFBO->width = _depthStencilTexture->getWidth(); + _gpuFBO->height = _depthStencilTexture->getHeight(); + return; + } +} + void GLES3Framebuffer::doInit(const FramebufferInfo & /*info*/) { _gpuFBO = ccnew GLES3GPUFramebuffer; - _gpuFBO->gpuRenderPass = static_cast(_renderPass)->gpuRenderPass(); + updateExtent(); + _gpuFBO->gpuRenderPass = static_cast(_renderPass)->gpuRenderPass(); _gpuFBO->gpuColorViews.resize(_colorTextures.size()); for (size_t i = 0; i < _colorTextures.size(); ++i) { auto *colorTexture = static_cast(_colorTextures.at(i)); @@ -58,6 +73,12 @@ void GLES3Framebuffer::doInit(const FramebufferInfo & /*info*/) { GLES3Device::getInstance()->framebufferHub()->connect(depthTexture->gpuTexture(), _gpuFBO); } + if (_depthStencilResolveTexture) { + auto *depthTexture = static_cast(_depthStencilResolveTexture); + _gpuFBO->gpuDepthStencilResolveView = depthTexture->gpuTextureView(); + GLES3Device::getInstance()->framebufferHub()->connect(depthTexture->gpuTexture(), _gpuFBO); + } + cmdFuncGLES3CreateFramebuffer(GLES3Device::getInstance(), _gpuFBO); } @@ -73,6 +94,10 @@ void GLES3Framebuffer::doDestroy() { auto *depthTexture = static_cast(_depthStencilTexture); GLES3Device::getInstance()->framebufferHub()->disengage(depthTexture->gpuTexture(), _gpuFBO); } + if (_depthStencilResolveTexture) { + auto *depthTexture = static_cast(_depthStencilResolveTexture); + GLES3Device::getInstance()->framebufferHub()->disengage(depthTexture->gpuTexture(), _gpuFBO); + } delete _gpuFBO; _gpuFBO = nullptr; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.h b/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.h index 50abda51bcb..15620265e8b 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.h +++ b/native/cocos/renderer/gfx-gles3/GLES3Framebuffer.h @@ -42,6 +42,7 @@ class CC_GLES3_API GLES3Framebuffer final : public Framebuffer { protected: void doInit(const FramebufferInfo &info) override; void doDestroy() override; + void updateExtent(); GLES3GPUFramebuffer *_gpuFBO = nullptr; }; diff --git a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h index 7c1317f2847..fa10675a6e8 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h +++ b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h @@ -130,10 +130,12 @@ struct GLES3GPUTexture { uint32_t size{0}; uint32_t arrayLayer{1}; uint32_t mipLevel{1}; - SampleCount samples{SampleCount::ONE}; + SampleCount samples{SampleCount::X1}; TextureFlags flags{TextureFlagBit::NONE}; + bool immutable{true}; bool isPowerOf2{false}; - bool memoryless{false}; + bool useRenderBuffer{false}; + bool allocateMemory{true}; // false if swapchain image or implicit ms render buffer. GLenum glTarget{0}; GLenum glInternalFmt{0}; GLenum glFormat{0}; @@ -320,63 +322,63 @@ struct GLES3GPUGeneralBarrier { GLbitfield glBarriersByRegion = 0U; }; -using DrawBuffer = std::vector; +using DrawBuffer = ccstd::vector; struct GLES3GPURenderPass { ColorAttachmentList colorAttachments; DepthStencilAttachment depthStencilAttachment; + DepthStencilAttachment depthStencilResolveAttachment; SubpassInfoList subpasses; SubpassDependencyList dependencies; - std::vector colors; - std::vector resolves; + ccstd::vector colors; + ccstd::vector resolves; uint32_t depthStencil = INVALID_BINDING; - std::vector indices; // offsets to GL_COLOR_ATTACHMENT_0 - std::vector drawBuffers; + uint32_t depthStencilResolve = INVALID_BINDING; + ccstd::vector indices; // offsets to GL_COLOR_ATTACHMENT_0 + ccstd::vector drawBuffers; }; class GLES3GPUFramebufferCacheMap; -class GLES3GPUFramebuffer final { -public: - GLES3GPURenderPass *gpuRenderPass{nullptr}; - GLES3GPUTextureViewList gpuColorViews; - GLES3GPUTextureView *gpuDepthStencilView{nullptr}; +struct GLES3GPUFramebufferObject { + void initialize(GLES3GPUSwapchain *swc = nullptr); - struct GLFramebufferInfo { - GLuint glFramebuffer{0U}; - uint32_t width{UINT_MAX}; - uint32_t height{UINT_MAX}; - }; - struct GLFramebuffer { - inline void initialize(GLES3GPUSwapchain *sc) { swapchain = sc; } - inline void initialize(const GLFramebufferInfo &info) { - _glFramebuffer = info.glFramebuffer; - _width = info.width; - _height = info.height; - } - inline GLuint getFramebuffer() const { return swapchain ? swapchain->glFramebuffer : _glFramebuffer; } - inline uint32_t getWidth() const { return swapchain ? swapchain->gpuColorTexture->width : _width; } - inline uint32_t getHeight() const { return swapchain ? swapchain->gpuColorTexture->height : _height; } + void bindColor(const GLES3GPUTextureView *texture, uint32_t colorIndex, const ColorAttachment &attachment); + void bindColorMultiSample(const GLES3GPUTextureView *texture, uint32_t colorIndex, GLint samples, const ColorAttachment &attachment); + void bindDepthStencil(const GLES3GPUTextureView *texture, const DepthStencilAttachment &attachment); + void bindDepthStencilMultiSample(const GLES3GPUTextureView *texture, GLint samples, const DepthStencilAttachment &attachment); - void destroy(GLES3GPUStateCache *cache, GLES3GPUFramebufferCacheMap *framebufferCacheMap); + bool isActive() const; + void finalize(GLES3GPUStateCache *cache); + void processLoad(GLenum target); + void processStore(GLenum target); + void destroy(GLES3GPUStateCache *cache, GLES3GPUFramebufferCacheMap *framebufferCacheMap); - GLES3GPUSwapchain *swapchain{nullptr}; + using Reference = std::pair; - private: - GLuint _glFramebuffer{0U}; - uint32_t _width{0U}; - uint32_t _height{0U}; - }; + GLuint handle{0}; + GLES3GPUSwapchain *swapchain{nullptr}; - struct Framebuffer { - GLFramebuffer framebuffer; + ccstd::vector colors; + Reference depthStencil{nullptr, 1}; + GLenum dsAttachment{GL_NONE}; - // for blit-based manual resolving - GLbitfield resolveMask{0U}; - GLFramebuffer resolveFramebuffer; - }; + ccstd::vector loadInvalidates; + ccstd::vector storeInvalidates; +}; - // one per subpass, if not using FBF - Framebuffer frameBuffer; +class GLES3GPUFramebuffer final { +public: + GLES3GPURenderPass *gpuRenderPass{nullptr}; + GLES3GPUTextureViewList gpuColorViews; + GLES3GPUTextureView *gpuDepthStencilView{nullptr}; + GLES3GPUTextureView *gpuDepthStencilResolveView{nullptr}; + + uint32_t width{UINT_MAX}; + uint32_t height{UINT_MAX}; + GLbitfield dsResolveMask = 0; + std::vector> colorBlitPairs; + GLES3GPUFramebufferObject framebuffer; + GLES3GPUFramebufferObject resolveFramebuffer; }; struct GLES3GPUDescriptorSetLayout { diff --git a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp index a4892670923..c409f6023a8 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp @@ -138,6 +138,10 @@ void GLES3PrimaryCommandBuffer::copyBuffersToTexture(const uint8_t *const *buffe } } +void GLES3PrimaryCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + copyTexture(srcTexture, dstTexture, regions, count); +} + void GLES3PrimaryCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { GLES3GPUTexture *gpuTextureSrc = nullptr; GLES3GPUTexture *gpuTextureDst = nullptr; diff --git a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h index 79d82f6bd31..3ae09735302 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h +++ b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h @@ -49,6 +49,7 @@ class CC_GLES3_API GLES3PrimaryCommandBuffer final : public GLES3CommandBuffer { void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const * /*buffers*/, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const * /*textures*/, uint32_t textureBarrierCount) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void beginQuery(QueryPool *queryPool, uint32_t id) override; void endQuery(QueryPool *queryPool, uint32_t id) override; void resetQueryPool(QueryPool *queryPool) override; diff --git a/native/cocos/renderer/gfx-gles3/GLES3RenderPass.cpp b/native/cocos/renderer/gfx-gles3/GLES3RenderPass.cpp index 2029f901eb3..76f8328171a 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3RenderPass.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3RenderPass.cpp @@ -44,6 +44,7 @@ void GLES3RenderPass::doInit(const RenderPassInfo & /*info*/) { _gpuRenderPass = ccnew GLES3GPURenderPass; _gpuRenderPass->colorAttachments = _colorAttachments; _gpuRenderPass->depthStencilAttachment = _depthStencilAttachment; + _gpuRenderPass->depthStencilResolveAttachment = _depthStencilResolveAttachment; _gpuRenderPass->subpasses = _subpasses; _gpuRenderPass->dependencies = _dependencies; @@ -59,14 +60,17 @@ void GLES3RenderPass::doInit(const RenderPassInfo & /*info*/) { if (_depthStencilAttachment.format != Format::UNKNOWN) { subpass.depthStencil = colorCount; } + if (_depthStencilResolveAttachment.format != Format::UNKNOWN) { + subpass.depthStencil = colorCount + 1; + } } else { // unify depth stencil index for (auto &subpass : _gpuRenderPass->subpasses) { - if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil > colorCount) { + if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil >= colorCount) { subpass.depthStencil = colorCount; } - if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencilResolve > colorCount) { - subpass.depthStencilResolve = colorCount; + if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencil >= colorCount) { + subpass.depthStencilResolve = colorCount + 1; } } } diff --git a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp index a4c729b6788..f5fc08157d6 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp @@ -71,7 +71,7 @@ void GLES3Texture::doInit(const TextureInfo & /*info*/) { cmdFuncGLES3CreateTexture(GLES3Device::getInstance(), _gpuTexture); - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES3Device::getInstance()->getMemoryStatus().textureSize += _size; CC_PROFILE_MEMORY_INC(Texture, _size); } @@ -101,7 +101,7 @@ void GLES3Texture::doDestroy() { CC_SAFE_DELETE(_gpuTextureView); if (_gpuTexture) { if (!_isTextureView) { - if (!_gpuTexture->memoryless) { + if (_gpuTexture->allocateMemory) { GLES3Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -115,7 +115,7 @@ void GLES3Texture::doDestroy() { } void GLES3Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { - if (!_isTextureView && !_gpuTexture->memoryless) { + if (!_isTextureView && _gpuTexture->allocateMemory) { GLES3Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -129,7 +129,7 @@ void GLES3Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { GLES3Device::getInstance()->framebufferHub()->update(_gpuTexture); - if (!_isTextureView && !_gpuTexture->memoryless) { + if (!_isTextureView && _gpuTexture->allocateMemory) { GLES3Device::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } @@ -167,7 +167,7 @@ void GLES3Texture::doInit(const SwapchainTextureInfo & /*info*/) { _gpuTexture->samples = _info.samples; _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; - _gpuTexture->memoryless = true; + _gpuTexture->allocateMemory = false; _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); _gpuTextureView = ccnew GLES3GPUTextureView; createTextureView(); diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h index 7567af5316f..bb38f1530cd 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h @@ -73,6 +73,7 @@ class CCMTLCommandBuffer final : public CommandBuffer { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm index e46e3eb8deb..84cd6f958e0 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm @@ -240,8 +240,6 @@ of this software and associated engine source code (the "Software"), a limited, if (subpasses[i].resolves.size() > j) { uint32_t resolve = subpasses[i].resolves[j]; auto *resolveTex = static_cast(colorTextures[resolve]); - if (resolveTex->textureInfo().samples != SampleCount::ONE) - continue; mtlRenderPassDescriptor.colorAttachments[color].resolveTexture = resolveTex->getMTLTexture(); mtlRenderPassDescriptor.colorAttachments[color].resolveLevel = 0; mtlRenderPassDescriptor.colorAttachments[color].resolveSlice = 0; @@ -388,19 +386,13 @@ of this software and associated engine source code (the "Software"), a limited, } if (subpass.depthStencilResolve != INVALID_BINDING) { - const CCMTLTexture *dsResolveTex = nullptr; - if (subpass.depthStencilResolve >= colorTextures.size()) { - dsResolveTex = static_cast(curFBO->getDepthStencilTexture()); - } else { - dsResolveTex = static_cast(colorTextures[subpass.depthStencilResolve]); - } - descriptor.depthAttachment.resolveTexture = dsResolveTex->getMTLTexture(); + descriptor.depthAttachment.resolveTexture = static_cast(curFBO->getDepthStencilTexture())->getMTLTexture(); descriptor.depthAttachment.resolveLevel = 0; descriptor.depthAttachment.resolveSlice = 0; descriptor.depthAttachment.resolveDepthPlane = 0; descriptor.depthAttachment.storeAction = subpass.depthResolveMode == ResolveMode::NONE ? MTLStoreActionMultisampleResolve : MTLStoreActionStoreAndMultisampleResolve; - descriptor.stencilAttachment.resolveTexture = dsResolveTex->getMTLTexture(); + descriptor.stencilAttachment.resolveTexture = static_cast(curFBO->getDepthStencilResolveTexture())->getMTLTexture(); descriptor.stencilAttachment.resolveLevel = 0; descriptor.stencilAttachment.resolveSlice = 0; descriptor.stencilAttachment.resolveDepthPlane = 0; @@ -919,6 +911,10 @@ of this software and associated engine source code (the "Software"), a limited, } } +void CCMTLCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + // not supported. +} + void CCMTLCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { ccstd::vector blitRegions(count); for (uint32_t i = 0; i < count; ++i) { diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.h b/native/cocos/renderer/gfx-metal/MTLDevice.h index 01068a1c787..e9cdecb3cf9 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.h +++ b/native/cocos/renderer/gfx-metal/MTLDevice.h @@ -62,7 +62,7 @@ class CCMTLDevice final : public Device { using Device::createRenderPass; using Device::createShader; using Device::createTexture; - + void frameSync() override; void acquire(Swapchain *const *swapchains, uint32_t count) override; @@ -116,6 +116,7 @@ class CCMTLDevice final : public Device { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) override; void copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) override; void getQueryPoolResults(QueryPool *queryPool) override; + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; void onMemoryWarning(); void initFormatFeatures(uint32_t family); diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.mm b/native/cocos/renderer/gfx-metal/MTLDevice.mm index daf0a1c42ba..5004befa238 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.mm +++ b/native/cocos/renderer/gfx-metal/MTLDevice.mm @@ -73,7 +73,7 @@ of this software and associated engine source code (the "Software"), a limited, bool CCMTLDevice::doInit(const DeviceInfo &info) { _gpuDeviceObj = ccnew CCMTLGPUDeviceObject; - + _currentFrameIndex = 0; id mtlDevice = MTLCreateSystemDefaultDevice(); @@ -87,7 +87,7 @@ of this software and associated engine source code (the "Software"), a limited, } _mtlFeatureSet = mu::highestSupportedFeatureSet(mtlDevice); _version = std::to_string(_mtlFeatureSet); - + const auto gpuFamily = mu::getGPUFamily(MTLFeatureSet(_mtlFeatureSet)); _indirectDrawSupported = mu::isIndirectDrawSupported(gpuFamily); _caps.maxVertexAttributes = mu::getMaxVertexAttributes(gpuFamily); @@ -138,13 +138,8 @@ of this software and associated engine source code (the "Software"), a limited, _features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = false; _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = false; _features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = true; - - const uint32_t samples[] = {2, 4, 8, 16, 32}; - for (auto sampleCount : samples) { - if ([mtlDevice supportsTextureSampleCount:sampleCount]) { - _gpuDeviceObj->supportSamples.emplace_back(sampleCount); - } - } + + _features[toNumber(Feature::MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL)] = [mtlDevice supportsFamily: MTLGPUFamilyApple3]; QueueInfo queueInfo; queueInfo.type = QueueType::GRAPHICS; @@ -152,7 +147,7 @@ of this software and associated engine source code (the "Software"), a limited, QueryPoolInfo queryPoolInfo{QueryType::OCCLUSION, DEFAULT_MAX_QUERY_OBJECTS, true}; _queryPool = createQueryPool(queryPoolInfo); - + CommandBufferInfo cmdBuffInfo; cmdBuffInfo.type = CommandBufferType::PRIMARY; cmdBuffInfo.queue = _queue; @@ -534,5 +529,22 @@ of this software and associated engine source code (the "Software"), a limited, _formatFeatures[toNumber(Format::RGB10A2)] |= FormatFeature::VERTEX_ATTRIBUTE; } +SampleCount CCMTLDevice::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + const SampleCount samples[] = { + SampleCount::X64, + SampleCount::X32, + SampleCount::X16, + SampleCount::X8, + SampleCount::X4, + SampleCount::X2, + }; + for (auto sampleCount : samples) { + if ([_mtlDevice supportsTextureSampleCount: static_cast(sampleCount)]) { + return sampleCount; + } + } + return SampleCount::X1; +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h index b508230d15b..d8aee7ec1f1 100644 --- a/native/cocos/renderer/gfx-metal/MTLGPUObjects.h +++ b/native/cocos/renderer/gfx-metal/MTLGPUObjects.h @@ -106,20 +106,20 @@ struct ResourceBinding { struct CCMTLGPUShader { ccstd::unordered_map blocks; ccstd::unordered_map samplers; - + ccstd::unordered_map resourceBinding; ccstd::vector inputs; ccstd::vector outputs; std::array workGroupSize{0, 0, 0}; - + NSString *shaderSrc = nil; bool specializeColor = true; uint32_t bufferIndex = 0; uint32_t samplerIndex = 0; - + std::string name; }; @@ -160,7 +160,7 @@ struct CCMTLGPUTextureViewObject { }; struct CCMTLGPUInputAssembler { - // + // }; struct CCMTLGPUDescriptor { @@ -326,7 +326,6 @@ struct CCMTLGPUCommandBufferObject { struct CCMTLGPUDeviceObject { CCMTLCommandBuffer* _transferCmdBuffer{nullptr}; - ccstd::vector supportSamples; }; struct CCMTLGPUQueryPool { diff --git a/native/cocos/renderer/gfx-metal/MTLPipelineState.mm b/native/cocos/renderer/gfx-metal/MTLPipelineState.mm index 7bd26adbae7..447ca460e19 100644 --- a/native/cocos/renderer/gfx-metal/MTLPipelineState.mm +++ b/native/cocos/renderer/gfx-metal/MTLPipelineState.mm @@ -333,7 +333,7 @@ of this software and associated engine source code (the "Software"), a limited, } } - SampleCount sample = SampleCount::ONE; + SampleCount sample = SampleCount::X1; Format depthStencilFormat; if (depthStencilTexIndex != INVALID_BINDING && depthStencilTexIndex < _renderPass->getColorAttachments().size()) { sample = _renderPass->getColorAttachments()[depthStencilTexIndex].sampleCount; diff --git a/native/cocos/renderer/gfx-metal/MTLTexture.h b/native/cocos/renderer/gfx-metal/MTLTexture.h index 65eaf60e101..38a48205a57 100644 --- a/native/cocos/renderer/gfx-metal/MTLTexture.h +++ b/native/cocos/renderer/gfx-metal/MTLTexture.h @@ -72,6 +72,8 @@ class CCMTLTexture final : public Texture { bool _isArray = false; bool _isPVRTC = false; + bool _allocateMemory = true; // allocate device memory by metal driver. + id _mtlTexture = nil; id _mtlTextureView = nil; }; diff --git a/native/cocos/renderer/gfx-metal/MTLTexture.mm b/native/cocos/renderer/gfx-metal/MTLTexture.mm index 5812ca53e10..edab24a636a 100644 --- a/native/cocos/renderer/gfx-metal/MTLTexture.mm +++ b/native/cocos/renderer/gfx-metal/MTLTexture.mm @@ -144,8 +144,10 @@ of this software and associated engine source code (the "Software"), a limited, return; } - CCMTLDevice::getInstance()->getMemoryStatus().textureSize += _size; - CC_PROFILE_MEMORY_INC(Texture, _size); + if (_allocateMemory) { + CCMTLDevice::getInstance()->getMemoryStatus().textureSize += _size; + CC_PROFILE_MEMORY_INC(Texture, _size); + } } void CCMTLTexture::doInit(const TextureViewInfo &info) { @@ -223,27 +225,15 @@ of this software and associated engine source code (the "Software"), a limited, descriptor.mipmapLevelCount = _info.levelCount; descriptor.arrayLength = _info.type == TextureType::CUBE ? 1 : _info.layerCount; - if (hasAllFlags(TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT, _info.usage) && mu::isImageBlockSupported()) { -#if MEMLESS_ON - // mac SDK mem_less unavailable before 11.0 - #if MAC_MEMORY_LESS_TEXTURE_SUPPORT || CC_PLATFORM == CC_PLATFORM_IOS - //xcode OS version warning - if (@available(macOS 11.0, *)) { + descriptor.storageMode = MTLStorageModePrivate; + if (@available(macos 11.0, ios 10.0, *)) { + bool memoryless = hasFlag(_info.flags, TextureFlagBit::LAZILY_ALLOCATED) && + hasFlag(_info.usage, TextureUsageBit::COLOR_ATTACHMENT) && + hasFlag(_info.usage, TextureUsageBit::DEPTH_STENCIL_ATTACHMENT); + if (memoryless) { descriptor.storageMode = MTLStorageModeMemoryless; - } else { - descriptor.storageMode = MTLStorageModePrivate; + _allocateMemory = false; } - #else - descriptor.storageMode = MTLStorageModePrivate; - #endif -#else - descriptor.storageMode = MTLStorageModePrivate; -#endif - } else if (hasFlag(_info.usage, TextureUsage::COLOR_ATTACHMENT) || - hasFlag(_info.usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT) || - hasFlag(_info.usage, TextureUsage::INPUT_ATTACHMENT) || - hasFlag(_info.usage, TextureUsage::STORAGE)) { - descriptor.storageMode = MTLStorageModePrivate; } id mtlDevice = id(CCMTLDevice::getInstance()->getMTLDevice()); @@ -262,8 +252,9 @@ of this software and associated engine source code (the "Software"), a limited, void CCMTLTexture::doDestroy() { //decrease only non-swapchain tex and have had been inited. - if (!_swapchain && _mtlTexture) { + if (!_swapchain && _mtlTexture && _allocateMemory) { CCMTLDevice::getInstance()->getMemoryStatus().textureSize -= _size; + CC_PROFILE_MEMORY_DEC(Texture, _size); } if (_swapchain) { @@ -281,8 +272,6 @@ of this software and associated engine source code (the "Software"), a limited, _mtlTexture = nil; } - CC_PROFILE_MEMORY_DEC(Texture, _size); - std::function destroyFunc = [mtlTexure]() { if (mtlTexure) { //TODO_Zeqiang: [mac12 | ios15, ...) validate here @@ -319,7 +308,7 @@ of this software and associated engine source code (the "Software"), a limited, // texture is a wrapper of drawable when _swapchain is active, drawable is not a resource alloc by gfx, // but the system so skip here. - if (!_swapchain) { + if (!_swapchain && _allocateMemory) { CCMTLDevice::getInstance()->getMemoryStatus().textureSize -= oldSize; CCMTLDevice::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_DEC(Texture, oldSize); diff --git a/native/cocos/renderer/gfx-metal/MTLUtils.mm b/native/cocos/renderer/gfx-metal/MTLUtils.mm index 605c895fef9..d2864e9b917 100644 --- a/native/cocos/renderer/gfx-metal/MTLUtils.mm +++ b/native/cocos/renderer/gfx-metal/MTLUtils.mm @@ -847,15 +847,7 @@ void main() { } NSUInteger mu::toMTLSampleCount(SampleCount count) { - auto* device = CCMTLDevice::getInstance(); - const auto& supportSamples = device->gpuObject()->supportSamples; - switch (count) { - case SampleCount::ONE: return 1; - case SampleCount::MULTIPLE_PERFORMANCE: return supportSamples.front(); - case SampleCount::MULTIPLE_BALANCE: return supportSamples[supportSamples.size() - 1]; - case SampleCount::MULTIPLE_QUALITY: - return supportSamples.back(); - } + return static_cast(count); } MTLSamplerAddressMode mu::toMTLSamplerAddressMode(Address mode) { diff --git a/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp b/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp index abae1798305..bab7e3c6ca5 100644 --- a/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp +++ b/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp @@ -418,6 +418,41 @@ void CommandBufferValidator::copyBuffersToTexture(const uint8_t *const *buffers, _actor->copyBuffersToTexture(buffers, textureValidator->getActor(), regions, count); } +void CommandBufferValidator::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + CC_ASSERT(isInited()); + CC_ASSERT(srcTexture && static_cast(srcTexture)->isInited()); + CC_ASSERT(dstTexture && static_cast(dstTexture)->isInited()); + const auto &srcInfo = srcTexture->getInfo(); + const auto &dstInfo = dstTexture->getInfo(); + + CC_ASSERT(srcInfo.format == dstInfo.format); + CC_ASSERT(srcInfo.format != Format::DEPTH_STENCIL && + srcInfo.format != Format::DEPTH); + + CC_ASSERT(srcInfo.samples > SampleCount::X1 && + dstInfo.samples == SampleCount::X1); + + CC_ASSERT(!_insideRenderPass); + + for (uint32_t i = 0; i < count; ++i) { + const auto ®ion = regions[i]; + CC_ASSERT(region.srcOffset.x + region.extent.width <= srcInfo.width); + CC_ASSERT(region.srcOffset.y + region.extent.height <= srcInfo.height); + CC_ASSERT(region.srcOffset.z + region.extent.depth <= srcInfo.depth); + + CC_ASSERT(region.dstOffset.x + region.extent.width <= dstInfo.width); + CC_ASSERT(region.dstOffset.y + region.extent.height <= dstInfo.height); + CC_ASSERT(region.dstOffset.z + region.extent.depth <= dstInfo.depth); + } + + Texture *actorSrcTexture = nullptr; + Texture *actorDstTexture = nullptr; + if (srcTexture) actorSrcTexture = static_cast(srcTexture)->getActor(); + if (dstTexture) actorDstTexture = static_cast(dstTexture)->getActor(); + + _actor->resolveTexture(actorSrcTexture, actorDstTexture, regions, count); +} + void CommandBufferValidator::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { CC_ASSERT(isInited()); CC_ASSERT(srcTexture && static_cast(srcTexture)->isInited()); @@ -453,9 +488,9 @@ void CommandBufferValidator::blitTexture(Texture *srcTexture, Texture *dstTextur CC_ASSERT(srcTexture && static_cast(srcTexture)->isInited()); CC_ASSERT(dstTexture && static_cast(dstTexture)->isInited()); // Blit on multisampled texture is not allowed. - CC_ASSERT(srcTexture->getInfo().samples == SampleCount::ONE); + CC_ASSERT(srcTexture->getInfo().samples == SampleCount::X1); // blit on multisampled texture is not allowed. - CC_ASSERT(dstTexture->getInfo().samples == SampleCount::ONE); + CC_ASSERT(dstTexture->getInfo().samples == SampleCount::X1); // Command 'blitTexture' must be recorded outside render passes. CC_ASSERT(!_insideRenderPass); diff --git a/native/cocos/renderer/gfx-validator/CommandBufferValidator.h b/native/cocos/renderer/gfx-validator/CommandBufferValidator.h index f7b0ee52748..3ec70240be2 100644 --- a/native/cocos/renderer/gfx-validator/CommandBufferValidator.h +++ b/native/cocos/renderer/gfx-validator/CommandBufferValidator.h @@ -58,6 +58,7 @@ class CC_DLL CommandBufferValidator final : public Agent { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-validator/DeviceValidator.cpp b/native/cocos/renderer/gfx-validator/DeviceValidator.cpp index f44d42aee1c..ff97a9910a1 100644 --- a/native/cocos/renderer/gfx-validator/DeviceValidator.cpp +++ b/native/cocos/renderer/gfx-validator/DeviceValidator.cpp @@ -352,5 +352,9 @@ void DeviceValidator::frameSync() { _actor->frameSync(); } +SampleCount DeviceValidator::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + return _actor->getMaxSampleCount(format, usage, flags); +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-validator/DeviceValidator.h b/native/cocos/renderer/gfx-validator/DeviceValidator.h index 111737a0869..4122d715e75 100644 --- a/native/cocos/renderer/gfx-validator/DeviceValidator.h +++ b/native/cocos/renderer/gfx-validator/DeviceValidator.h @@ -95,7 +95,7 @@ class CC_DLL DeviceValidator final : public Agent { inline uint64_t currentFrame() const { return _currentFrame; } void enableAutoBarrier(bool enable) override; - + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; protected: static DeviceValidator *instance; diff --git a/native/cocos/renderer/gfx-validator/FramebufferValidator.cpp b/native/cocos/renderer/gfx-validator/FramebufferValidator.cpp index bf6c868d479..8c4166bbb8e 100644 --- a/native/cocos/renderer/gfx-validator/FramebufferValidator.cpp +++ b/native/cocos/renderer/gfx-validator/FramebufferValidator.cpp @@ -54,6 +54,9 @@ void FramebufferValidator::doInit(const FramebufferInfo &info) { if (info.renderPass->getDepthStencilAttachment().format != Format::UNKNOWN) { CC_ASSERT(info.depthStencilTexture); } + if (info.renderPass->getDepthStencilResolveAttachment().format != Format::UNKNOWN) { + CC_ASSERT(info.depthStencilResolveTexture); + } for (uint32_t i = 0U; i < info.colorTextures.size(); ++i) { const auto &desc = info.renderPass->getColorAttachments()[i]; @@ -67,6 +70,11 @@ void FramebufferValidator::doInit(const FramebufferInfo &info) { CC_ASSERT(hasFlag(info.depthStencilTexture->getInfo().usage, TextureUsageBit::DEPTH_STENCIL_ATTACHMENT)); CC_ASSERT(info.depthStencilTexture->getFormat() == info.renderPass->getDepthStencilAttachment().format); } + if (info.depthStencilResolveTexture) { + CC_ASSERT(static_cast(info.depthStencilResolveTexture)->isInited()); + CC_ASSERT(hasFlag(info.depthStencilResolveTexture->getInfo().usage, TextureUsageBit::DEPTH_STENCIL_ATTACHMENT)); + CC_ASSERT(info.depthStencilResolveTexture->getFormat() == info.renderPass->getDepthStencilResolveAttachment().format); + } /////////// execute /////////// @@ -79,6 +87,9 @@ void FramebufferValidator::doInit(const FramebufferInfo &info) { if (info.depthStencilTexture) { actorInfo.depthStencilTexture = static_cast(info.depthStencilTexture)->getActor(); } + if (info.depthStencilResolveTexture) { + actorInfo.depthStencilResolveTexture = static_cast(info.depthStencilResolveTexture)->getActor(); + } actorInfo.renderPass = static_cast(info.renderPass)->getActor(); _actor->initialize(actorInfo); diff --git a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp index fb62c102e02..7aefa9312fc 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp @@ -168,15 +168,17 @@ void CCVKCommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo } ccstd::vector &clearValues = _curGPURenderPass->clearValues; - bool depthEnabled = _curGPURenderPass->depthStencilAttachment.format != Format::UNKNOWN; - size_t attachmentCount = depthEnabled ? clearValues.size() - 1 : clearValues.size(); - + size_t attachmentCount = _curGPURenderPass->colorAttachments.size(); for (size_t i = 0U; i < attachmentCount; ++i) { clearValues[i].color = {{colors[i].x, colors[i].y, colors[i].z, colors[i].w}}; } - if (depthEnabled) { + + if (_curGPURenderPass->depthStencilAttachment.format != Format::UNKNOWN) { clearValues[attachmentCount].depthStencil = {depth, stencil}; } + if (_curGPURenderPass->depthStencilResolveAttachment.format != Format::UNKNOWN) { + clearValues[attachmentCount + 1].depthStencil = {depth, stencil}; + } Rect safeArea{ std::min(renderArea.x, static_cast(_curGPUFBO->width)), @@ -516,6 +518,50 @@ void CCVKCommandBuffer::copyBuffersToTexture(const uint8_t *const *buffers, Text cmdFuncCCVKCopyBuffersToTexture(CCVKDevice::getInstance(), buffers, static_cast(texture)->gpuTexture(), regions, count, _gpuCommandBuffer); } +void CCVKCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { + VkImageAspectFlags srcAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + VkImageAspectFlags dstAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + VkImage srcImage = VK_NULL_HANDLE; + VkImage dstImage = VK_NULL_HANDLE; + + auto getImage = [](Texture * texture) -> auto { + CCVKGPUTexture *gpuTexture = static_cast(texture)->gpuTexture(); + return gpuTexture->swapchain ? std::pair{gpuTexture->aspectMask, gpuTexture->swapchainVkImages[gpuTexture->swapchain->curImageIndex]} : std::pair{gpuTexture->aspectMask, gpuTexture->vkImage}; + }; + + std::tie(srcAspectMask, srcImage) = getImage(srcTexture); + std::tie(dstAspectMask, dstImage) = getImage(dstTexture); + + ccstd::vector resolveRegions(count); + for (uint32_t i = 0U; i < count; ++i) { + const TextureCopy ®ion = regions[i]; + auto &resolveRegion = resolveRegions[i]; + + resolveRegion.srcSubresource.aspectMask = srcAspectMask; + resolveRegion.srcSubresource.mipLevel = region.srcSubres.mipLevel; + resolveRegion.srcSubresource.baseArrayLayer = region.srcSubres.baseArrayLayer; + resolveRegion.srcSubresource.layerCount = region.srcSubres.layerCount; + + resolveRegion.dstSubresource.aspectMask = dstAspectMask; + resolveRegion.dstSubresource.mipLevel = region.dstSubres.mipLevel; + resolveRegion.dstSubresource.baseArrayLayer = region.dstSubres.baseArrayLayer; + resolveRegion.dstSubresource.layerCount = region.dstSubres.layerCount; + + resolveRegion.srcOffset.x = region.srcOffset.x; + resolveRegion.srcOffset.y = region.srcOffset.y; + resolveRegion.srcOffset.z = region.srcOffset.z; + + resolveRegion.dstOffset.x = region.dstOffset.x; + resolveRegion.dstOffset.y = region.dstOffset.y; + resolveRegion.dstOffset.z = region.dstOffset.z; + + resolveRegion.extent.width = region.extent.width; + resolveRegion.extent.height = region.extent.height; + resolveRegion.extent.depth = region.extent.depth; + } + vkCmdResolveImage(_gpuCommandBuffer->vkCommandBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, count, resolveRegions.data()); +} + void CCVKCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { VkImageAspectFlags srcAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; VkImageAspectFlags dstAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; diff --git a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h index 3438684cbe9..1eae85158ed 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h +++ b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h @@ -58,6 +58,7 @@ class CC_VULKAN_API CCVKCommandBuffer final : public CommandBuffer { void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp index e39045970b6..34604b72268 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp @@ -119,11 +119,6 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { if (!gpuTexture->size) return; gpuTexture->aspectMask = mapVkImageAspectFlags(gpuTexture->format); - // storage images has to be in general layout - // if (hasFlag(gpuTexture->usage, TextureUsageBit::STORAGE)) gpuTexture->flags |= TextureFlagBit::GENERAL_LAYOUT; - // remove stencil aspect for depth textures with sampled usage - if (hasFlag(gpuTexture->usage, TextureUsageBit::SAMPLED)) gpuTexture->aspectMask &= ~VK_IMAGE_ASPECT_STENCIL_BIT; - auto createFn = [device, gpuTexture](VkImage *pVkImage, VmaAllocation *pVmaAllocation) { VkFormat vkFormat = mapVkFormat(gpuTexture->format, device->gpuDevice()); VkFormatFeatureFlags features = mapVkFormatFeatureFlags(gpuTexture->usage); @@ -135,10 +130,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { return; } - VkImageUsageFlags usageFlags = mapVkImageUsageFlagBits(gpuTexture->usage); - if (hasFlag(gpuTexture->flags, TextureFlags::GEN_MIPMAP)) { - usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - } + VkImageUsageFlags usageFlags = mapVkImageUsageFlags(gpuTexture->usage, gpuTexture->flags); VkImageCreateInfo createInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; createInfo.flags = mapVkImageCreateFlags(gpuTexture->type); @@ -147,7 +139,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { createInfo.extent = {gpuTexture->width, gpuTexture->height, gpuTexture->depth}; createInfo.mipLevels = gpuTexture->mipLevels; createInfo.arrayLayers = gpuTexture->arrayLayers; - createInfo.samples = device->gpuContext()->getSampleCountForAttachments(gpuTexture->format, vkFormat, gpuTexture->samples); + createInfo.samples = static_cast(gpuTexture->samples); createInfo.tiling = VK_IMAGE_TILING_OPTIMAL; createInfo.usage = usageFlags; createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; @@ -156,23 +148,25 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; VmaAllocationInfo res; - - if (ENABLE_LAZY_ALLOCATION && hasAllFlags(TEXTURE_USAGE_TRANSIENT, gpuTexture->usage)) { - createInfo.usage = usageFlags | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + const VkFlags lazilyAllocatedFilterFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + if (hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED) && + (lazilyAllocatedFilterFlags & usageFlags) == usageFlags) { allocInfo.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED; VkResult result = vmaCreateImage(device->gpuDevice()->memoryAllocator, &createInfo, &allocInfo, pVkImage, pVmaAllocation, &res); if (!result) { - gpuTexture->memoryless = true; + gpuTexture->allocateMemory = false; return; } - // feature not present, fallback - createInfo.usage = usageFlags; + // feature not present, fallback to device memory allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; } - gpuTexture->memoryless = false; + gpuTexture->allocateMemory = true; VK_CHECK(vmaCreateImage(device->gpuDevice()->memoryAllocator, &createInfo, &allocInfo, pVkImage, pVmaAllocation, &res)); }; @@ -190,7 +184,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { gpuTexture->swapchainVkImages[i] = gpuTexture->swapchain->swapchainImages[i]; } } - gpuTexture->memoryless = true; + gpuTexture->allocateMemory = false; } else if (hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_NORMAL)) { gpuTexture->vkImage = gpuTexture->externalVKImage; } else { @@ -383,11 +377,18 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende ccstd::vector shadingRateReferences; const size_t colorAttachmentCount = gpuRenderPass->colorAttachments.size(); - const size_t hasDepth = gpuRenderPass->depthStencilAttachment.format != Format::UNKNOWN ? 1 : 0; - attachmentDescriptions.assign(colorAttachmentCount + hasDepth, {VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2}); - gpuRenderPass->clearValues.resize(colorAttachmentCount + hasDepth); - beginAccessInfos.resize(colorAttachmentCount + hasDepth); - endAccessInfos.resize(colorAttachmentCount + hasDepth); + const size_t hasDepthStencil = gpuRenderPass->depthStencilAttachment.format != Format::UNKNOWN ? 1 : 0; + const size_t hasDepthResolve = gpuRenderPass->depthStencilResolveAttachment.format != Format::UNKNOWN ? 1 : 0; + auto attachmentCount = static_cast(colorAttachmentCount + hasDepthStencil + hasDepthResolve); + uint32_t depthIndex = colorAttachmentCount; + uint32_t stencilIndex = colorAttachmentCount + 1; + + const bool hasStencil = GFX_FORMAT_INFOS[toNumber(gpuRenderPass->depthStencilAttachment.format)].hasStencil; + + attachmentDescriptions.assign(attachmentCount, {VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2}); + gpuRenderPass->clearValues.resize(attachmentCount); + beginAccessInfos.resize(attachmentCount); + endAccessInfos.resize(attachmentCount); shadingRateReferences.resize(gpuRenderPass->subpasses.size(), {VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR}); for (size_t i = 0U; i < colorAttachmentCount; ++i) { @@ -396,34 +397,43 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende getInitialFinalLayout(device, static_cast(attachment.barrier), false); VkFormat vkFormat = mapVkFormat(attachment.format, device->gpuDevice()); - bool hasStencil = GFX_FORMAT_INFOS[toNumber(attachment.format)].hasStencil; - VkSampleCountFlagBits samples = device->gpuContext()->getSampleCountForAttachments(attachment.format, vkFormat, attachment.sampleCount); - attachmentDescriptions[i].format = vkFormat; - attachmentDescriptions[i].samples = samples; + attachmentDescriptions[i].samples = static_cast(attachment.sampleCount); attachmentDescriptions[i].loadOp = mapVkLoadOp(attachment.loadOp); attachmentDescriptions[i].storeOp = mapVkStoreOp(attachment.storeOp); - attachmentDescriptions[i].stencilLoadOp = hasStencil ? attachmentDescriptions[i].loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachmentDescriptions[i].stencilStoreOp = hasStencil ? attachmentDescriptions[i].storeOp : VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachmentDescriptions[i].initialLayout = attachment.loadOp == gfx::LoadOp::DISCARD ? VK_IMAGE_LAYOUT_UNDEFINED : initialLayout; attachmentDescriptions[i].finalLayout = finalLayout; } - if (hasDepth) { - const DepthStencilAttachment &depthStencilAttachment = gpuRenderPass->depthStencilAttachment; - auto [initialLayout, finalLayout] = getInitialFinalLayout(device, static_cast(depthStencilAttachment.barrier), true); - - VkFormat vkFormat = mapVkFormat(depthStencilAttachment.format, device->gpuDevice()); - bool hasStencil = GFX_FORMAT_INFOS[toNumber(depthStencilAttachment.format)].hasStencil; - VkSampleCountFlagBits samples = device->gpuContext()->getSampleCountForAttachments(depthStencilAttachment.format, vkFormat, depthStencilAttachment.sampleCount); - - attachmentDescriptions[colorAttachmentCount].format = vkFormat; - attachmentDescriptions[colorAttachmentCount].samples = samples; - attachmentDescriptions[colorAttachmentCount].loadOp = mapVkLoadOp(depthStencilAttachment.depthLoadOp); - attachmentDescriptions[colorAttachmentCount].storeOp = mapVkStoreOp(depthStencilAttachment.depthStoreOp); - attachmentDescriptions[colorAttachmentCount].stencilLoadOp = hasStencil ? mapVkLoadOp(depthStencilAttachment.stencilLoadOp) : VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachmentDescriptions[colorAttachmentCount].stencilStoreOp = hasStencil ? mapVkStoreOp(depthStencilAttachment.stencilStoreOp) : VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachmentDescriptions[colorAttachmentCount].initialLayout = depthStencilAttachment.depthLoadOp == gfx::LoadOp::DISCARD ? VK_IMAGE_LAYOUT_UNDEFINED : initialLayout; - attachmentDescriptions[colorAttachmentCount].finalLayout = finalLayout; + if (hasDepthStencil) { + const DepthStencilAttachment &attachment = gpuRenderPass->depthStencilAttachment; + auto [initialLayout, finalLayout] = getInitialFinalLayout(device, static_cast(attachment.barrier), true); + + VkFormat vkFormat = mapVkFormat(attachment.format, device->gpuDevice()); + attachmentDescriptions[depthIndex].format = vkFormat; + attachmentDescriptions[depthIndex].samples = static_cast(attachment.sampleCount); + attachmentDescriptions[depthIndex].loadOp = mapVkLoadOp(attachment.depthLoadOp); + attachmentDescriptions[depthIndex].storeOp = mapVkStoreOp(attachment.depthStoreOp); + attachmentDescriptions[depthIndex].stencilLoadOp = hasStencil ? mapVkLoadOp(attachment.stencilLoadOp) : VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[depthIndex].stencilStoreOp = hasStencil ? mapVkStoreOp(attachment.stencilStoreOp) : VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[depthIndex].initialLayout = attachment.depthLoadOp == gfx::LoadOp::DISCARD ? VK_IMAGE_LAYOUT_UNDEFINED : initialLayout; + attachmentDescriptions[depthIndex].finalLayout = finalLayout; + } + if (hasDepthResolve) { + const DepthStencilAttachment &attachment = gpuRenderPass->depthStencilResolveAttachment; + auto [initialLayout, finalLayout] = getInitialFinalLayout(device, static_cast(attachment.barrier), true); + + VkFormat vkFormat = mapVkFormat(attachment.format, device->gpuDevice()); + + attachmentDescriptions[stencilIndex].format = vkFormat; + attachmentDescriptions[stencilIndex].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[stencilIndex].loadOp = mapVkLoadOp(attachment.depthLoadOp); + attachmentDescriptions[stencilIndex].storeOp = mapVkStoreOp(attachment.depthStoreOp); + attachmentDescriptions[stencilIndex].stencilLoadOp = hasStencil ? mapVkLoadOp(attachment.stencilLoadOp) : VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[stencilIndex].stencilStoreOp = hasStencil ? mapVkStoreOp(attachment.stencilStoreOp) : VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[stencilIndex].initialLayout = attachment.depthLoadOp == gfx::LoadOp::DISCARD ? VK_IMAGE_LAYOUT_UNDEFINED : initialLayout; + attachmentDescriptions[stencilIndex].finalLayout = finalLayout; } size_t subpassCount = gpuRenderPass->subpasses.size(); @@ -444,7 +454,6 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende } } for (uint32_t color : subpassInfo.colors) { - const ColorAttachment &desc = gpuRenderPass->colorAttachments[color]; const VkAttachmentDescription2 &attachment = attachmentDescriptions[color]; bool appearsInInput = std::find(subpassInfo.inputs.begin(), subpassInfo.inputs.end(), color) != subpassInfo.inputs.end(); VkImageLayout layout = appearsInInput ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -454,44 +463,22 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende for (uint32_t resolveIn : subpassInfo.resolves) { VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; auto resolve = resolveIn == gfx::INVALID_BINDING ? VK_ATTACHMENT_UNUSED : resolveIn; + CC_ASSERT(INVALID_BINDING == VK_ATTACHMENT_UNUSED); attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, resolve, layout, VK_IMAGE_ASPECT_COLOR_BIT}); } if (subpassInfo.depthStencil != INVALID_BINDING) { - Format dsFormat{Format::UNKNOWN}; - if (subpassInfo.depthStencil >= colorAttachmentCount) { - const DepthStencilAttachment &desc = gpuRenderPass->depthStencilAttachment; - const VkAttachmentDescription2 &attachment = attachmentDescriptions.back(); - dsFormat = desc.format; - sampleCount = std::max(sampleCount, attachment.samples); - } else { - const ColorAttachment &desc = gpuRenderPass->colorAttachments[subpassInfo.depthStencil]; - const VkAttachmentDescription2 &attachment = attachmentDescriptions[subpassInfo.depthStencil]; - dsFormat = desc.format; - sampleCount = std::max(sampleCount, attachment.samples); - } + const VkAttachmentDescription2 &attachment = attachmentDescriptions[subpassInfo.depthStencil]; + sampleCount = std::max(sampleCount, attachment.samples); bool appearsInInput = std::find(subpassInfo.inputs.begin(), subpassInfo.inputs.end(), subpassInfo.depthStencil) != subpassInfo.inputs.end(); - VkImageAspectFlags aspect = GFX_FORMAT_INFOS[toNumber(dsFormat)].hasStencil - ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT - : VK_IMAGE_ASPECT_DEPTH_BIT; + VkImageAspectFlags aspect = hasStencil ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; VkImageLayout layout = appearsInInput ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, subpassInfo.depthStencil, layout, aspect}); } if (subpassInfo.depthStencilResolve != INVALID_BINDING) { - Format dsFormat{Format::UNKNOWN}; - if (subpassInfo.depthStencilResolve >= colorAttachmentCount) { - const DepthStencilAttachment &desc = gpuRenderPass->depthStencilAttachment; - dsFormat = desc.format; - } else { - const ColorAttachment &desc = gpuRenderPass->colorAttachments[subpassInfo.depthStencilResolve]; - dsFormat = desc.format; - } - - VkImageAspectFlags aspect = GFX_FORMAT_INFOS[toNumber(dsFormat)].hasStencil - ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT - : VK_IMAGE_ASPECT_DEPTH_BIT; + VkImageAspectFlags aspect = hasStencil ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachmentReferences.push_back({VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, nullptr, subpassInfo.depthStencilResolve, layout, aspect}); } @@ -550,8 +537,14 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende VkResolveModeFlagBits depthResolveMode = VK_RESOLVE_MODES[toNumber(subpassInfo.depthResolveMode)]; VkResolveModeFlagBits stencilResolveMode = VK_RESOLVE_MODES[toNumber(subpassInfo.stencilResolveMode)]; - if ((depthResolveMode & prop.supportedDepthResolveModes) == 0) depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; - if ((stencilResolveMode & prop.supportedStencilResolveModes) == 0) stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; + if ((depthResolveMode & prop.supportedDepthResolveModes) == 0) { + depthResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; + CC_LOG_WARNING("render pass depth resolve mode [%u] not supported, use Sample0 instead.", toNumber(subpassInfo.depthResolveMode)); + } + if ((stencilResolveMode & prop.supportedStencilResolveModes) == 0) { + stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; + CC_LOG_WARNING("render pass stencil resolve mode [%u] not supported, use Sample0 instead.", toNumber(subpassInfo.stencilResolveMode)); + } if (!prop.independentResolveNone && stencilResolveMode != depthResolveMode) { stencilResolveMode = depthResolveMode; @@ -575,6 +568,7 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende } size_t dependencyCount = gpuRenderPass->dependencies.size(); + gpuRenderPass->hasSelfDependency.resize(subpassCount, false); dependencyManager.clear(); bool manuallyDeduce = true; @@ -587,8 +581,6 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende if (!manuallyDeduce) { // offset = 0U; ccstd::unordered_set subpassExternalFilter; - - gpuRenderPass->hasSelfDependency.resize(subpassCount, false); for (uint32_t i = 0U; i < dependencyCount; ++i) { const auto &dependency{gpuRenderPass->dependencies[i]}; VkSubpassDependency2 vkDependency{VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2}; @@ -672,8 +664,8 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende } } }; - attachmentStatistics.resize(colorAttachmentCount + hasDepth); - for (uint32_t i = 0U; i < utils ::toUint(colorAttachmentCount + hasDepth); ++i) { + attachmentStatistics.resize(attachmentCount); + for (uint32_t i = 0U; i < utils ::toUint(attachmentCount); ++i) { attachmentStatistics[i].clear(); calculateLifeCycle(i, attachmentStatistics[i]); CC_ASSERT(attachmentStatistics[i].loadSubpass != VK_SUBPASS_EXTERNAL && @@ -700,7 +692,7 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende VkSubpassDependency2 beginDependency; uint32_t lastLoadSubpass{VK_SUBPASS_EXTERNAL}; bool beginDependencyValid{false}; - for (uint32_t i = 0U; i < utils ::toUint(colorAttachmentCount + hasDepth); ++i) { + for (uint32_t i = 0U; i < attachmentCount; ++i) { auto &statistics = attachmentStatistics[i]; if (lastLoadSubpass != statistics.loadSubpass) { if (beginDependencyValid) dependencyManager.append(beginDependency); @@ -732,7 +724,7 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende VkSubpassDependency2 endDependency; uint32_t lastStoreSubpass{VK_SUBPASS_EXTERNAL}; bool endDependencyValid{false}; - for (uint32_t i = 0U; i < utils ::toUint(colorAttachmentCount + hasDepth); ++i) { + for (uint32_t i = 0U; i < attachmentCount; ++i) { auto &statistics = attachmentStatistics[i]; if (lastStoreSubpass != statistics.storeSubpass) { if (endDependencyValid) dependencyManager.append(endDependency); @@ -762,7 +754,7 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; return dependency; }; - for (size_t i = 0U; i < colorAttachmentCount + hasDepth; ++i) { + for (size_t i = 0U; i < attachmentCount; ++i) { auto &statistics{attachmentStatistics[i]}; const AttachmentStatistics::SubpassRef *prevRef{nullptr}; @@ -791,8 +783,12 @@ void cmdFuncCCVKCreateRenderPass(CCVKDevice *device, CCVKGPURenderPass *gpuRende void cmdFuncCCVKCreateFramebuffer(CCVKDevice *device, CCVKGPUFramebuffer *gpuFramebuffer) { size_t colorViewCount = gpuFramebuffer->gpuColorViews.size(); - bool hasDepth = gpuFramebuffer->gpuRenderPass->depthStencilAttachment.format != Format::UNKNOWN; - ccstd::vector attachments(colorViewCount + hasDepth); + const auto *gpuRenderPass = gpuFramebuffer->gpuRenderPass.get(); + const size_t hasDepthStencil = gpuRenderPass->depthStencilAttachment.format != Format::UNKNOWN ? 1 : 0; + const size_t hasDepthResolve = gpuRenderPass->depthStencilResolveAttachment.format != Format::UNKNOWN ? 1 : 0; + auto attachmentCount = static_cast(colorViewCount + hasDepthStencil + hasDepthResolve); + + ccstd::vector attachments(attachmentCount); VkFramebufferCreateInfo createInfo{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; createInfo.width = createInfo.height = UINT_MAX; @@ -812,14 +808,20 @@ void cmdFuncCCVKCreateFramebuffer(CCVKDevice *device, CCVKGPUFramebuffer *gpuFra createInfo.height = std::min(createInfo.height, std::max(1U, gpuFramebuffer->gpuColorViews[i]->gpuTexture->height >> gpuFramebuffer->gpuColorViews[i]->baseLevel)); } } - if (hasDepth) { + if (hasDepthStencil) { if (gpuFramebuffer->gpuDepthStencilView->gpuTexture->swapchain) { gpuFramebuffer->swapchain = gpuFramebuffer->gpuDepthStencilView->gpuTexture->swapchain; swapchainImageIndices |= (1 << colorViewCount); } else { attachments[colorViewCount] = gpuFramebuffer->gpuDepthStencilView->vkImageView; } + createInfo.width = std::min(createInfo.width, std::max(1U, gpuFramebuffer->gpuDepthStencilView->gpuTexture->width >> gpuFramebuffer->gpuDepthStencilView->baseLevel)); + createInfo.height = std::min(createInfo.height, std::max(1U, gpuFramebuffer->gpuDepthStencilView->gpuTexture->height >> gpuFramebuffer->gpuDepthStencilView->baseLevel)); + } + if (hasDepthResolve) { + attachments[colorViewCount + 1] = gpuFramebuffer->gpuDepthStencilResolveView->vkImageView; } + gpuFramebuffer->isOffscreen = !swapchainImageIndices; gpuFramebuffer->width = createInfo.width; gpuFramebuffer->height = createInfo.height; @@ -1593,33 +1595,6 @@ bool CCVKGPURenderPass::hasShadingAttachment(uint32_t subPassId) const { return subpasses[subPassId].shadingRate != INVALID_BINDING; } -VkSampleCountFlagBits CCVKGPUContext::getSampleCountForAttachments(Format format, VkFormat vkFormat, SampleCount sampleCount) const { - if (sampleCount <= SampleCount::ONE) return VK_SAMPLE_COUNT_1_BIT; - - static ccstd::unordered_map cacheMap; - if (!cacheMap.count(format)) { - bool hasDepth = GFX_FORMAT_INFOS[toNumber(format)].hasDepth; - VkImageUsageFlags usages = hasDepth ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - - VkImageFormatProperties properties; - vkGetPhysicalDeviceImageFormatProperties(physicalDevice, vkFormat, VK_IMAGE_TYPE_2D, - VK_IMAGE_TILING_OPTIMAL, usages, 0, &properties); - cacheMap[format] = properties.sampleCounts; - } - - VkSampleCountFlags availableSampleCounts = cacheMap[format]; - - auto requestedSampleCount = VK_SAMPLE_COUNT_FLAGS[toNumber(sampleCount)]; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_64_BIT) return VK_SAMPLE_COUNT_64_BIT; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_32_BIT) return VK_SAMPLE_COUNT_32_BIT; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_16_BIT) return VK_SAMPLE_COUNT_16_BIT; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_8_BIT) return VK_SAMPLE_COUNT_8_BIT; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_4_BIT) return VK_SAMPLE_COUNT_4_BIT; - if (requestedSampleCount & availableSampleCounts & VK_SAMPLE_COUNT_2_BIT) return VK_SAMPLE_COUNT_2_BIT; - - return VK_SAMPLE_COUNT_1_BIT; -} - void CCVKGPUBarrierManager::update(CCVKGPUTransportHub *transportHub) { if (_buffersToBeChecked.empty() && _texturesToBeChecked.empty()) return; diff --git a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp index acc577be13c..85d9bacdfcb 100644 --- a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp @@ -768,6 +768,7 @@ void CCVKDevice::initDeviceFeature() { _features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = true; _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = true; _features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = true; + _features[toNumber(Feature::MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL)] = checkExtension("VK_KHR_depth_stencil_resolve"); } void CCVKDevice::initFormatFeature() { @@ -1084,5 +1085,23 @@ static VkResult VKAPI_PTR vkCreateRenderPass2KHRFallback( return vkCreateRenderPass(device, &renderPassCreateInfo, pAllocator, pRenderPass); } +SampleCount CCVKDevice::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { + auto vkFormat = mapVkFormat(format, gpuDevice()); + auto usages = mapVkImageUsageFlags(usage, flags); + + VkImageFormatProperties imageFormatProperties = {}; + vkGetPhysicalDeviceImageFormatProperties(_gpuContext->physicalDevice, vkFormat, VK_IMAGE_TYPE_2D, + VK_IMAGE_TILING_OPTIMAL, usages, 0, &imageFormatProperties); + + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_64_BIT) return SampleCount::X64; + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_32_BIT) return SampleCount::X32; + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_16_BIT) return SampleCount::X16; + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_8_BIT) return SampleCount::X8; + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_4_BIT) return SampleCount::X4; + if (imageFormatProperties.sampleCounts & VK_SAMPLE_COUNT_2_BIT) return SampleCount::X2; + + return SampleCount::X1; +} + } // namespace gfx } // namespace cc diff --git a/native/cocos/renderer/gfx-vulkan/VKDevice.h b/native/cocos/renderer/gfx-vulkan/VKDevice.h index c53f6cb20ad..4d7d9c938a8 100644 --- a/native/cocos/renderer/gfx-vulkan/VKDevice.h +++ b/native/cocos/renderer/gfx-vulkan/VKDevice.h @@ -105,7 +105,7 @@ class CC_VULKAN_API CCVKDevice final : public Device { void waitAllFences(); void updateBackBufferCount(uint32_t backBufferCount); - + SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override; protected: static CCVKDevice *instance; diff --git a/native/cocos/renderer/gfx-vulkan/VKFramebuffer.cpp b/native/cocos/renderer/gfx-vulkan/VKFramebuffer.cpp index efb463ba464..7bf4d5d2881 100644 --- a/native/cocos/renderer/gfx-vulkan/VKFramebuffer.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKFramebuffer.cpp @@ -54,6 +54,11 @@ void CCVKFramebuffer::doInit(const FramebufferInfo & /*info*/) { _gpuFBO->gpuDepthStencilView = depthTex->gpuTextureView(); } + if (_depthStencilResolveTexture) { + auto *depthTex = static_cast(_depthStencilResolveTexture); + _gpuFBO->gpuDepthStencilResolveView = depthTex->gpuTextureView(); + } + cmdFuncCCVKCreateFramebuffer(CCVKDevice::getInstance(), _gpuFBO); } diff --git a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h index c47e4a76fae..02d77f4a581 100644 --- a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h +++ b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h @@ -71,8 +71,6 @@ class CCVKGPUContext final { return std::strcmp(ext, extension.c_str()) == 0; }); } - - VkSampleCountFlagBits getSampleCountForAttachments(Format format, VkFormat vkFormat, SampleCount sampleCount) const; }; struct CCVKAccessInfo { @@ -119,6 +117,7 @@ class CCVKGPURenderPass final : public CCVKGPUDeviceObject { ColorAttachmentList colorAttachments; DepthStencilAttachment depthStencilAttachment; + DepthStencilAttachment depthStencilResolveAttachment; SubpassInfoList subpasses; SubpassDependencyList dependencies; @@ -148,10 +147,19 @@ struct CCVKGPUTexture : public CCVKGPUDeviceObject { uint32_t size = 0U; uint32_t arrayLayers = 1U; uint32_t mipLevels = 1U; - SampleCount samples = SampleCount::ONE; + SampleCount samples = SampleCount::X1; TextureFlags flags = TextureFlagBit::NONE; VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bool memoryless = false; + + /* + * allocate and bind memory by Texture. + * If any of the following conditions are met, then the statement is false + * 1. Texture is a swapchain image. + * 2. Texture has flag LAZILY_ALLOCATED. + * 3. Memory bound manually bound. + * 4. Sparse Image. + */ + bool allocateMemory = true; VkImage vkImage = VK_NULL_HANDLE; VmaAllocation vmaAllocation = VK_NULL_HANDLE; @@ -258,6 +266,7 @@ struct CCVKGPUFramebuffer : public CCVKGPUDeviceObject { ConstPtr gpuRenderPass; ccstd::vector> gpuColorViews; ConstPtr gpuDepthStencilView; + ConstPtr gpuDepthStencilResolveView; VkFramebuffer vkFramebuffer = VK_NULL_HANDLE; std::vector vkFrameBuffers; CCVKGPUSwapchain *swapchain = nullptr; diff --git a/native/cocos/renderer/gfx-vulkan/VKRenderPass.cpp b/native/cocos/renderer/gfx-vulkan/VKRenderPass.cpp index 8597bf22a8b..ce705b9ee89 100644 --- a/native/cocos/renderer/gfx-vulkan/VKRenderPass.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKRenderPass.cpp @@ -41,6 +41,7 @@ void CCVKRenderPass::doInit(const RenderPassInfo & /*info*/) { _gpuRenderPass = ccnew CCVKGPURenderPass; _gpuRenderPass->colorAttachments = _colorAttachments; _gpuRenderPass->depthStencilAttachment = _depthStencilAttachment; + _gpuRenderPass->depthStencilResolveAttachment = _depthStencilResolveAttachment; _gpuRenderPass->subpasses = _subpasses; _gpuRenderPass->dependencies = _dependencies; @@ -56,14 +57,17 @@ void CCVKRenderPass::doInit(const RenderPassInfo & /*info*/) { if (_depthStencilAttachment.format != Format::UNKNOWN) { subpass.depthStencil = colorCount; } + if (_depthStencilResolveAttachment.format != Format::UNKNOWN) { + subpass.depthStencilResolve = colorCount + 1; + } } else { // unify depth stencil index for (auto &subpass : _gpuRenderPass->subpasses) { - if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil > colorCount) { + if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil >= colorCount) { subpass.depthStencil = colorCount; } - if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencilResolve > colorCount) { - subpass.depthStencilResolve = colorCount; + if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencilResolve >= colorCount) { + subpass.depthStencilResolve = colorCount + 1; } } } diff --git a/native/cocos/renderer/gfx-vulkan/VKTexture.cpp b/native/cocos/renderer/gfx-vulkan/VKTexture.cpp index 8af0555a995..ccb83024090 100644 --- a/native/cocos/renderer/gfx-vulkan/VKTexture.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKTexture.cpp @@ -60,7 +60,7 @@ void CCVKTexture::createTexture(uint32_t width, uint32_t height, uint32_t size, if (_swapchain != nullptr) { _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); - _gpuTexture->memoryless = true; + _gpuTexture->allocateMemory = false; } _gpuTexture->type = _info.type; @@ -121,14 +121,14 @@ void CCVKTexture::doInit(const SwapchainTextureInfo & /*info*/) { void CCVKGPUTexture::init() { cmdFuncCCVKCreateTexture(CCVKDevice::getInstance(), this); - if (!memoryless) { + if (allocateMemory) { CCVKDevice::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } } void CCVKGPUTexture::shutdown() { - if (!memoryless) { + if (allocateMemory) { CCVKDevice::getInstance()->getMemoryStatus().textureSize -= size; CC_PROFILE_MEMORY_DEC(Texture, size); } diff --git a/native/cocos/renderer/gfx-vulkan/VKUtils.cpp b/native/cocos/renderer/gfx-vulkan/VKUtils.cpp index 2b328b47e18..4d9c78dfc6e 100644 --- a/native/cocos/renderer/gfx-vulkan/VKUtils.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKUtils.cpp @@ -229,8 +229,8 @@ VkFormatFeatureFlags mapVkFormatFeatureFlags(TextureUsage usage) { return static_cast(flags); } -VkImageUsageFlagBits mapVkImageUsageFlagBits(TextureUsage usage) { - uint32_t flags = 0U; +VkImageUsageFlags mapVkImageUsageFlags(TextureUsage usage, TextureFlags textureFlags) { + VkImageUsageFlags flags = 0; if (hasFlag(usage, TextureUsage::TRANSFER_SRC)) flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; if (hasFlag(usage, TextureUsage::TRANSFER_DST)) flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; if (hasFlag(usage, TextureUsage::SAMPLED)) flags |= VK_IMAGE_USAGE_SAMPLED_BIT; @@ -239,7 +239,14 @@ VkImageUsageFlagBits mapVkImageUsageFlagBits(TextureUsage usage) { if (hasFlag(usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; if (hasFlag(usage, TextureUsage::INPUT_ATTACHMENT)) flags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; if (hasFlag(usage, TextureUsage::SHADING_RATE)) flags |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; - return static_cast(flags); + + if (hasFlag(textureFlags, TextureFlags::GEN_MIPMAP)) { + flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + if (hasFlag(textureFlags, TextureFlags::LAZILY_ALLOCATED)) { + flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + } + return flags; } VkImageAspectFlags mapVkImageAspectFlags(Format format) { @@ -493,17 +500,6 @@ const VkStencilFaceFlags VK_STENCIL_FACE_FLAGS[] = { VK_STENCIL_FACE_FRONT_AND_BACK, }; -const VkSampleCountFlags VK_SAMPLE_COUNT_FLAGS[] = { - VK_SAMPLE_COUNT_1_BIT, - VK_SAMPLE_COUNT_2_BIT, -#if CC_PLATFORM == CC_PLATFORM_ANDROID || CC_PLATFORM == CC_PLATFORM_IOS - VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_2_BIT, -#else // desktop platforms - VK_SAMPLE_COUNT_8_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_2_BIT, -#endif - VK_SAMPLE_COUNT_16_BIT | VK_SAMPLE_COUNT_8_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_2_BIT, -}; - const VkAccessFlags FULL_ACCESS_FLAGS = VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | diff --git a/native/cocos/renderer/gfx-vulkan/VKUtils.h b/native/cocos/renderer/gfx-vulkan/VKUtils.h index 4b7ac04abee..26bf88d35ea 100644 --- a/native/cocos/renderer/gfx-vulkan/VKUtils.h +++ b/native/cocos/renderer/gfx-vulkan/VKUtils.h @@ -58,7 +58,7 @@ VkAttachmentStoreOp mapVkStoreOp(StoreOp storeOp); VkBufferUsageFlagBits mapVkBufferUsageFlagBits(BufferUsage usage); VkImageType mapVkImageType(TextureType type); VkFormatFeatureFlags mapVkFormatFeatureFlags(TextureUsage usage); -VkImageUsageFlagBits mapVkImageUsageFlagBits(TextureUsage usage); +VkImageUsageFlags mapVkImageUsageFlags(TextureUsage usage, TextureFlags textureFlags); VkImageAspectFlags mapVkImageAspectFlags(Format format); VkImageCreateFlags mapVkImageCreateFlags(TextureType type); VkImageViewType mapVkImageViewType(TextureType viewType); @@ -94,7 +94,6 @@ extern const VkPipelineBindPoint VK_PIPELINE_BIND_POINTS[]; extern const VkResolveModeFlagBits VK_RESOLVE_MODES[]; extern const VkImageLayout VK_IMAGE_LAYOUTS[]; extern const VkStencilFaceFlags VK_STENCIL_FACE_FLAGS[]; -extern const VkSampleCountFlags VK_SAMPLE_COUNT_FLAGS[]; extern const VkAccessFlags FULL_ACCESS_FLAGS; } // namespace gfx diff --git a/native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.cpp b/native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.cpp index b9f2c8b0703..432b1ad9ef7 100644 --- a/native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.cpp +++ b/native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.cpp @@ -169,7 +169,7 @@ void CCWGPUDescriptorSetLayout::updateTextureLayout(uint8_t binding, const CCWGP const CCWGPUTexture *ccTex = static_cast(texture->isTextureView() ? texture->getViewInfo().texture : texture); TextureType type = ccTex->getViewInfo().type; (*iter).texture.viewDimension = toWGPUTextureViewDimension(type); - (*iter).texture.multisampled = ccTex->getInfo().samples != SampleCount::ONE; + (*iter).texture.multisampled = ccTex->getInfo().samples != SampleCount::X1; } } else { (*iter).texture.nextInChain = nullptr; diff --git a/native/cocos/renderer/gfx-wgpu/WGPURenderPass.cpp b/native/cocos/renderer/gfx-wgpu/WGPURenderPass.cpp index 467e0f1639d..dc425a1ae64 100644 --- a/native/cocos/renderer/gfx-wgpu/WGPURenderPass.cpp +++ b/native/cocos/renderer/gfx-wgpu/WGPURenderPass.cpp @@ -36,13 +36,13 @@ using namespace emscripten; class CCWGPURenderPassHelper { public: explicit CCWGPURenderPassHelper(const RenderPassInfo &info) { - SampleCount samples = SampleCount::ONE; + SampleCount samples = SampleCount::X1; for (size_t i = 0; i < info.colorAttachments.size(); i++) { colors[i].loadOp = toWGPULoadOp(info.colorAttachments[i].loadOp); colors[i].storeOp = toWGPUStoreOp(info.colorAttachments[i].storeOp); colors[i].clearValue = defaultClearColor; // TODO_Zeqaing : subpass - if (info.colorAttachments[i].sampleCount != SampleCount::ONE) + if (info.colorAttachments[i].sampleCount != SampleCount::X1) samples = info.colorAttachments[i].sampleCount; } @@ -54,7 +54,7 @@ class CCWGPURenderPassHelper { depthStencils[0].depthClearValue = defaultClearDepth; depthStencils[0].depthReadOnly = false; depthStencils[0].stencilReadOnly = false; - if (samples == SampleCount::ONE) + if (samples == SampleCount::X1) samples = info.depthStencilAttachment.sampleCount; renderPassDesc = ccnew WGPURenderPassDescriptor; @@ -106,4 +106,4 @@ void CCWGPURenderPass::doDestroy() { } } // namespace gfx -} // namespace cc \ No newline at end of file +} // namespace cc diff --git a/native/cocos/renderer/gfx-wgpu/WGPUTexture.cpp b/native/cocos/renderer/gfx-wgpu/WGPUTexture.cpp index d3f486c99ba..77f723e0c13 100644 --- a/native/cocos/renderer/gfx-wgpu/WGPUTexture.cpp +++ b/native/cocos/renderer/gfx-wgpu/WGPUTexture.cpp @@ -234,7 +234,7 @@ CCWGPUTexture *CCWGPUTexture::defaultCommonTexture() { .flags = TextureFlagBit::NONE, .layerCount = 1, .levelCount = 1, - .samples = SampleCount::ONE, + .samples = SampleCount::X1, .depth = 1, .externalRes = nullptr, }; @@ -256,7 +256,7 @@ CCWGPUTexture *CCWGPUTexture::defaultStorageTexture() { .flags = TextureFlagBit::NONE, .layerCount = 1, .levelCount = 1, - .samples = SampleCount::ONE, + .samples = SampleCount::X1, .depth = 1, .externalRes = nullptr, }; diff --git a/native/cocos/renderer/gfx-wgpu/WGPUUtils.h b/native/cocos/renderer/gfx-wgpu/WGPUUtils.h index 1ab82fb8fc3..f79f50c4896 100644 --- a/native/cocos/renderer/gfx-wgpu/WGPUUtils.h +++ b/native/cocos/renderer/gfx-wgpu/WGPUUtils.h @@ -395,21 +395,7 @@ static WGPUShaderStageFlags toWGPUShaderStageFlag(ShaderStageFlagBit flag) { // TODO_Zeqiang: more flexible strategy static uint32_t toWGPUSampleCount(SampleCount sampleCount) { - // TODO_Zeqiang: msaa - return 1; - switch (sampleCount) { - case SampleCount::ONE: - return 1; - case SampleCount::MULTIPLE_PERFORMANCE: - return 4; - case SampleCount::MULTIPLE_BALANCE: - return 4; - case SampleCount::MULTIPLE_QUALITY: - return 4; - default: - printf("unsupport sampleCount %d.", sampleCount); - return 1; - } + return static_cast(sampleCount); } // NONE = 0, diff --git a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h index 91bf73662c2..0ac3830c647 100644 --- a/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h +++ b/native/cocos/renderer/pipeline/custom/FGDispatcherTypes.h @@ -114,6 +114,7 @@ struct LayoutAccess { struct FGRenderPassInfo { std::vector colorAccesses; LayoutAccess dsAccess; + LayoutAccess dsResolveAccess; gfx::RenderPassInfo rpInfo; std::vector orderedViews; bool needResolve{false}; diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index cdd02a4f30c..1a2cffac76a 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -1233,6 +1233,11 @@ void buildBarriers(FrameGraphDispatcher &fgDispatcher) { const auto &dsAccess = fgRenderpassInfo.dsAccess; dsAttachment.barrier = getGeneralBarrier(cc::gfx::Device::getInstance(), dsAccess.prevAccess, dsAccess.nextAccess); } + auto &dsResolveAttachment = fgRenderpassInfo.rpInfo.depthStencilResolveAttachment; + if (dsResolveAttachment.format != gfx::Format::UNKNOWN) { + const auto &dsAccess = fgRenderpassInfo.dsResolveAccess; + dsResolveAttachment.barrier = getGeneralBarrier(cc::gfx::Device::getInstance(), dsAccess.prevAccess, dsAccess.nextAccess); + } } } } @@ -2124,7 +2129,7 @@ bool checkResolveResource(const Graphs &graphs, uint32_t vertID, uint32_t /*pass } void fillRenderPassInfo(gfx::LoadOp loadOp, gfx::StoreOp storeOp, AttachmentType attachmentType, gfx::RenderPassInfo &rpInfo, uint32_t index, const ResourceDesc &viewDesc, bool resolve) { - if (attachmentType != AttachmentType::DEPTH_STENCIL || resolve) { + if (attachmentType != AttachmentType::DEPTH_STENCIL) { auto &colorAttachment = rpInfo.colorAttachments[index]; if (colorAttachment.format == gfx::Format::UNKNOWN) { colorAttachment.format = viewDesc.format; @@ -2136,7 +2141,9 @@ void fillRenderPassInfo(gfx::LoadOp loadOp, gfx::StoreOp storeOp, AttachmentType } } else { - auto &depthStencilAttachment = rpInfo.depthStencilAttachment; + auto &depthStencilAttachment = resolve ? + rpInfo.depthStencilResolveAttachment : + rpInfo.depthStencilAttachment; if (depthStencilAttachment.format == gfx::Format::UNKNOWN) { depthStencilAttachment.format = viewDesc.format; depthStencilAttachment.depthLoadOp = loadOp; @@ -2232,8 +2239,14 @@ void processRasterPass(const Graphs &graphs, uint32_t passID, const RasterPass & colorSize -= hasDS; const auto &subpasses = pass.subpassGraph.subpasses; uint32_t count = 0; - auto resolveNum = std::accumulate(subpasses.begin(), subpasses.end(), 0, [](uint32_t initVal, const Subpass &subpass) { - return initVal + subpass.resolvePairs.size(); + const auto &resg = resourceGraph; + auto resolveNum = std::accumulate(subpasses.begin(), subpasses.end(), 0, [&resg](uint32_t initVal, const Subpass &subpass) { + auto iter = std::find_if(subpass.resolvePairs.begin(), subpass.resolvePairs.end(), [&resg](const auto &pair) { + auto resID = vertex(pair.target, resg); + const auto& desc = get(ResourceGraph::DescTag{}, resg, resID); + return desc.format == gfx::Format::DEPTH_STENCIL || desc.format == gfx::Format::DEPTH; + }); + return initVal + subpass.resolvePairs.size() - (iter != subpass.resolvePairs.end()); }); colorSize += resolveNum; rpInfo.colorAttachments.resize(colorSize); @@ -2432,17 +2445,17 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub attachmentType = viewDesc.format == gfx::Format::DEPTH_STENCIL ? AttachmentType::DEPTH_STENCIL : AttachmentType::RENDER_TARGET; if (attachmentType == AttachmentType::DEPTH_STENCIL) { subpassInfo.depthStencilResolve = slot; - subpassInfo.depthResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode; - subpassInfo.stencilResolveMode = gfx::ResolveMode::AVERAGE; // resolveiter->mode1; + subpassInfo.depthResolveMode = gfx::ResolveMode::SAMPLE_ZERO; // resolveiter->mode; + subpassInfo.stencilResolveMode = gfx::ResolveMode::SAMPLE_ZERO; // resolveiter->mode1; + fgRenderpassInfo.dsResolveAccess.nextAccess = nextAccess; } else { auto indexIter = std::find(fgRenderpassInfo.orderedViews.begin(), fgRenderpassInfo.orderedViews.end(), resolveIter->source.c_str()); auto srcIndex = indexIter == fgRenderpassInfo.orderedViews.end() ? fgRenderpassInfo.orderedViews.size() : std::distance(fgRenderpassInfo.orderedViews.begin(), indexIter); subpassInfo.resolves[srcIndex] = slot; + fgRenderpassInfo.colorAccesses[slot].nextAccess = nextAccess; } accessType = AccessType::WRITE; - - fgRenderpassInfo.colorAccesses[slot].nextAccess = nextAccess; } else { const auto &view = pass.rasterViews.at(resName); attachmentType = view.attachmentType; @@ -2477,7 +2490,11 @@ void processRasterSubpass(const Graphs &graphs, uint32_t passID, const RasterSub auto nextAccess = head->attachmentStatus[localSlot].accessFlag; if (attachmentType == AttachmentType::DEPTH_STENCIL) { - fgRenderpassInfo.dsAccess.prevAccess = prevAccess; + if (resolveView) { + fgRenderpassInfo.dsResolveAccess.prevAccess = prevAccess; + } else { + fgRenderpassInfo.dsAccess.prevAccess = prevAccess; + } } else { fgRenderpassInfo.colorAccesses[slot].prevAccess = prevAccess; } diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index bb71c6192c2..8f5d97636ab 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -97,6 +97,7 @@ struct RenderGraphVisitorContext { void clear(gfx::RenderPassInfo& info) { info.colorAttachments.clear(); info.depthStencilAttachment = {}; + info.depthStencilResolveAttachment = {}; info.subpasses.clear(); info.dependencies.clear(); } @@ -183,22 +184,23 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( // uint32_t dsvCount = 0; uint32_t index = 0; - for (const auto nameIn : passViews) { + for (const auto& nameIn : passViews) { const char* name = nameIn.c_str(); bool colorLikeView{true}; - bool dsAttachment{false}; + bool dsResolveAttachment{false}; auto clearColor = gfx::Color{}; auto iter = pass.rasterViews.find(name); if(iter != pass.rasterViews.end()) { const auto& view = iter->second; colorLikeView = view.attachmentType == AttachmentType::RENDER_TARGET || view.attachmentType == AttachmentType::SHADING_RATE; - dsAttachment = !colorLikeView; clearColor = view.clearColor; } else { // resolves const auto resID = vertex(name, ctx.resourceGraph); const auto& desc = get(ResourceGraph::DescTag{}, ctx.resourceGraph, resID); - CC_ASSERT(hasResolve && desc.sampleCount == gfx::SampleCount::ONE); + CC_ASSERT(hasResolve && desc.sampleCount == gfx::SampleCount::X1); + colorLikeView = desc.format != gfx::Format::DEPTH_STENCIL && desc.format != gfx::Format::DEPTH; + dsResolveAttachment = !colorLikeView; } if (colorLikeView) { // RenderTarget @@ -246,22 +248,23 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( std::ignore = view; CC_EXPECTS(false); }); - } else if (dsAttachment) { // DepthStencil - data.clearDepth = clearColor.x; - data.clearStencil = static_cast(clearColor.y); + } else { // DepthStencil + if (!dsResolveAttachment) { + data.clearDepth = clearColor.x; + data.clearStencil = static_cast(clearColor.y); + } + + auto &dsAttachment = dsResolveAttachment ? fbInfo.depthStencilResolveTexture : fbInfo.depthStencilTexture; - if (!fbInfo.depthStencilTexture) { - auto resID = findVertex(name, resg); - visitObject( + auto resID = findVertex(name, resg); + visitObject( resID, resg, [&](const ManagedTexture& tex) { CC_EXPECTS(tex.texture); - CC_EXPECTS(!fbInfo.depthStencilTexture); - fbInfo.depthStencilTexture = tex.texture.get(); + dsAttachment = tex.texture.get(); }, [&](const IntrusivePtr& tex) { - CC_EXPECTS(!fbInfo.depthStencilTexture); - fbInfo.depthStencilTexture = tex.get(); + dsAttachment = tex.get(); }, [&](const FormatView& view) { std::ignore = view; @@ -274,7 +277,6 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( [](const auto& /*unused*/) { CC_EXPECTS(false); }); - } } ++index; } @@ -1145,7 +1147,7 @@ struct RenderGraphUploadVisitor : boost::dfs_visitor<> { const auto& subpass = get(RasterSubpassTag{}, vertID, ctx.g); // render pass const auto& layoutName = get(RenderGraph::LayoutTag{}, ctx.g, vertID); - + auto parentLayoutID = ctx.currentPassLayoutID; auto layoutID = parentLayoutID; if (!layoutName.empty()) { @@ -1261,7 +1263,7 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { } const auto& nodeID = iter->second; auto iter2 = ctx.barrierMap.find(nodeID); - if (iter2 != ctx.barrierMap.end() && iter2->second.subpassBarriers.empty()) { + if (iter2 != ctx.barrierMap.end()) { submitBarriers(iter2->second.blockBarrier.frontBarriers); } } @@ -1272,7 +1274,7 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { } const auto& nodeID = iter->second; auto iter2 = ctx.barrierMap.find(nodeID); - if (iter2 != ctx.barrierMap.end() && iter2->second.subpassBarriers.empty()) { + if (iter2 != ctx.barrierMap.end()) { submitBarriers(iter2->second.blockBarrier.rearBarriers); } } @@ -2239,7 +2241,7 @@ void NativePipeline::executeRenderGraph(const RenderGraph& rg) { RenderGraphVisitor visitor{{}, ctx}; auto colors = rg.colors(scratch); for (const auto vertID : ctx.g.sortedVertices) { - if (holds(vertID, ctx.g) || holds(vertID, ctx.g)) { + if (holds(vertID, ctx.g) || holds(vertID, ctx.g) || holds(vertID, ctx.g)) { boost::depth_first_visit(fg, vertID, visitor, get(colors, ctx.g)); } } diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index f03a804616f..69932c1ca75 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -92,9 +92,10 @@ uint32_t NativePipeline::addRenderWindow(const ccstd::string &name, gfx::Format desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED; + desc.flags = ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED | + ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST; CC_EXPECTS(renderWindow); @@ -138,9 +139,9 @@ uint32_t NativePipeline::addStorageBuffer(const ccstd::string &name, gfx::Format desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::STORAGE; + desc.flags = ResourceFlags::STORAGE | ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST; return addVertex( ManagedBufferTag{}, @@ -162,9 +163,10 @@ uint32_t NativePipeline::addRenderTarget(const ccstd::string &name, gfx::Format desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED; + desc.flags = ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED | + ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST; return addVertex( ManagedTextureTag{}, @@ -186,9 +188,10 @@ uint32_t NativePipeline::addDepthStencil(const ccstd::string &name, gfx::Format desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::DEPTH_STENCIL_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED; + desc.flags = ResourceFlags::DEPTH_STENCIL_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT | ResourceFlags::SAMPLED | + ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST; CC_EXPECTS(residency == ResourceResidency::MANAGED || residency == ResourceResidency::MEMORYLESS); @@ -220,7 +223,7 @@ uint32_t NativePipeline::addResource(const ccstd::string& name, ResourceDimensio static_cast(mipLevels), format, sampleCount, - gfx::TextureFlagBit::NONE, + residency == ResourceResidency::MEMORYLESS ? gfx::TextureFlagBit::LAZILY_ALLOCATED : gfx::TextureFlagBit::NONE, flags, }; return addVertex( @@ -277,9 +280,9 @@ uint32_t NativePipeline::addStorageTexture(const ccstd::string &name, gfx::Forma desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::STORAGE | ResourceFlags::SAMPLED; + desc.flags = ResourceFlags::STORAGE | ResourceFlags::SAMPLED | ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST;; CC_EXPECTS(residency == ResourceResidency::MANAGED || residency == ResourceResidency::MEMORYLESS); @@ -306,9 +309,9 @@ uint32_t NativePipeline::addShadingRateTexture(const ccstd::string &name, uint32 desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = gfx::Format::R8UI; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; - desc.flags = ResourceFlags::SHADING_RATE | ResourceFlags::STORAGE | ResourceFlags::SAMPLED; + desc.flags = ResourceFlags::SHADING_RATE | ResourceFlags::STORAGE | ResourceFlags::SAMPLED | ResourceFlags::TRANSFER_SRC | ResourceFlags::TRANSFER_DST; CC_EXPECTS(residency == ResourceResidency::MANAGED || residency == ResourceResidency::MEMORYLESS); @@ -342,7 +345,7 @@ uint32_t NativePipeline::addCustomBuffer( desc.depthOrArraySize = 1; desc.mipLevels = 1; desc.format = gfx::Format::UNKNOWN; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = gfx::TextureFlagBit::NONE; desc.flags = ResourceFlags::NONE; @@ -374,7 +377,7 @@ uint32_t NativePipeline::addCustomTexture( desc.depthOrArraySize = info.layerCount; desc.mipLevels = info.levelCount; desc.format = info.format; - desc.sampleCount = gfx::SampleCount::ONE; + desc.sampleCount = gfx::SampleCount::X1; desc.textureFlags = info.flags; desc.flags = ResourceFlags::NONE; diff --git a/native/cocos/renderer/pipeline/custom/NativeResourceGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeResourceGraph.cpp index 20709a6f97f..984e215a9ad 100644 --- a/native/cocos/renderer/pipeline/custom/NativeResourceGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeResourceGraph.cpp @@ -126,7 +126,7 @@ gfx::TextureInfo getTextureInfo(const ResourceDesc& desc, bool bCube = false) { } // usage - TextureUsage usage = TextureUsage::SAMPLED | TextureUsage::TRANSFER_SRC | TextureUsage::TRANSFER_DST; + TextureUsage usage = TextureUsage::NONE; if (any(desc.flags & ResourceFlags::COLOR_ATTACHMENT)) { usage |= TextureUsage::COLOR_ATTACHMENT; } @@ -143,6 +143,15 @@ gfx::TextureInfo getTextureInfo(const ResourceDesc& desc, bool bCube = false) { if (any(desc.flags & ResourceFlags::SHADING_RATE)) { usage |= TextureUsage::SHADING_RATE; } + if (any(desc.flags & ResourceFlags::SAMPLED)) { + usage |= TextureUsage::SAMPLED; + } + if (any(desc.flags & ResourceFlags::TRANSFER_SRC)) { + usage |= TextureUsage::TRANSFER_SRC; + } + if (any(desc.flags & ResourceFlags::TRANSFER_DST)) { + usage |= TextureUsage::TRANSFER_DST; + } return { type, diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index 56da2384bb5..77d8b9c0b16 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -102,6 +102,8 @@ enum class ResourceFlags : uint32_t { DEPTH_STENCIL_ATTACHMENT = 0x20, INPUT_ATTACHMENT = 0x40, SHADING_RATE = 0x80, + TRANSFER_SRC = 0x100, + TRANSFER_DST = 0x200 }; constexpr ResourceFlags operator|(const ResourceFlags lhs, const ResourceFlags rhs) noexcept { diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index ab3562cda73..0e2ac6e971c 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -166,7 +166,7 @@ struct ResourceDesc { uint16_t depthOrArraySize{0}; uint16_t mipLevels{0}; gfx::Format format{gfx::Format::UNKNOWN}; - gfx::SampleCount sampleCount{gfx::SampleCount::ONE}; + gfx::SampleCount sampleCount{gfx::SampleCount::X1}; gfx::TextureFlagBit textureFlags{gfx::TextureFlagBit::NONE}; ResourceFlags flags{ResourceFlags::NONE}; }; diff --git a/native/cocos/renderer/pipeline/custom/test/test.h b/native/cocos/renderer/pipeline/custom/test/test.h index 645e6d624f6..b749412635b 100644 --- a/native/cocos/renderer/pipeline/custom/test/test.h +++ b/native/cocos/renderer/pipeline/custom/test/test.h @@ -567,117 +567,117 @@ static void runTestGraph(const RenderGraph &renderGraph, const ResourceGraph &re using cc::gfx::TextureFlagBit; \ ResourceInfo resources = { \ {"0", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"1", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"2", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"3", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"4", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"5", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"6", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"7", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"8", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"9", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"10", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"11", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"12", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"13", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"14", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"15", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"16", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"17", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"18", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::MANAGED}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"19", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::EXTERNAL}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"20", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::EXTERNAL}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"21", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::EXTERNAL}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ {"22", \ - {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::ONE, TextureFlagBit::NONE, \ + {ResourceDimension::TEXTURE2D, 4, 960, 640, 1, 0, Format::RGBA8, SampleCount::X1, TextureFlagBit::NONE, \ ResourceFlags::SAMPLED | ResourceFlags::COLOR_ATTACHMENT | ResourceFlags::INPUT_ATTACHMENT}, \ {ResourceResidency::BACKBUFFER}, \ {AccessFlagBit::FRAGMENT_SHADER_READ_TEXTURE | AccessFlagBit::COLOR_ATTACHMENT_WRITE}}, \ diff --git a/native/cocos/renderer/pipeline/shadow/ShadowFlow.cpp b/native/cocos/renderer/pipeline/shadow/ShadowFlow.cpp index adc4639b49c..115e2fe5ca8 100644 --- a/native/cocos/renderer/pipeline/shadow/ShadowFlow.cpp +++ b/native/cocos/renderer/pipeline/shadow/ShadowFlow.cpp @@ -283,7 +283,7 @@ void ShadowFlow::initShadowFrameBuffer(const RenderPipeline *pipeline, const sce const gfx::ColorAttachment colorAttachment{ format, - gfx::SampleCount::ONE, + gfx::SampleCount::X1, gfx::LoadOp::CLEAR, gfx::StoreOp::STORE, device->getGeneralBarrier({ @@ -294,7 +294,7 @@ void ShadowFlow::initShadowFrameBuffer(const RenderPipeline *pipeline, const sce const gfx::DepthStencilAttachment depthStencilAttachment{ gfx::Format::DEPTH, - gfx::SampleCount::ONE, + gfx::SampleCount::X1, gfx::LoadOp::CLEAR, gfx::StoreOp::DISCARD, gfx::LoadOp::CLEAR, diff --git a/native/tools/swig-config/gfx.i b/native/tools/swig-config/gfx.i index 452f7b47ae9..a0944e0ffd7 100644 --- a/native/tools/swig-config/gfx.i +++ b/native/tools/swig-config/gfx.i @@ -65,6 +65,7 @@ namespace cc { namespace gfx { %ignore CommandBuffer::execute; %ignore CommandBuffer::updateBuffer; +%ignore CommandBuffer::resolveTexture; %ignore CommandBuffer::copyBuffersToTexture; %rename(drawWithInfo) CommandBuffer::draw(const DrawInfo&); From 14a4ded42acdcf4d3112202064e7492d9a9d1286 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 11 Jul 2023 19:42:17 +0800 Subject: [PATCH 45/57] adding gpu driven --- cocos/rendering/custom/pipeline.ts | 7 +- cocos/rendering/custom/render-graph.ts | 1 + cocos/rendering/custom/types.ts | 2 +- .../pipeline/custom/NativeExecutor.cpp | 1 + .../pipeline/custom/NativePipeline.cpp | 174 ++++++++++++++++++ .../pipeline/custom/NativePipelineTypes.cpp | 3 +- .../pipeline/custom/NativePipelineTypes.h | 3 + .../pipeline/custom/NativeRenderGraph.cpp | 47 +++++ .../pipeline/custom/RenderCommonTypes.h | 2 +- .../pipeline/custom/RenderGraphTypes.h | 1 + .../pipeline/custom/RenderInterfaceTypes.h | 8 + 11 files changed, 245 insertions(+), 4 deletions(-) diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index f54a721df84..3d151f338f6 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -39,7 +39,7 @@ import { MacroRecord } from '../../render-scene/core/pass-utils'; import { PipelineSceneData } from '../pipeline-scene-data'; import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; import { RenderWindow } from '../../render-scene/core/render-window'; -import { Model } from '../../render-scene/scene'; +import { Light, Model } from '../../render-scene/scene'; import { SpotLight } from '../../render-scene/scene/spot-light'; /** @@ -1376,6 +1376,11 @@ export interface Pipeline extends BasicPipeline { * @param movePairs @en Array of move source and target @zh 移动来源与目标的数组 */ addMovePass (movePairs: MovePair[]): void; + addBuiltinGpuCullingPass ( + camera: Camera, + hzbName?: string, + light?: Light | null): void; + addBuiltinHzbGenerationPass (sourceDepthStencilName: string, targetHzbName: string): void; /** * @experimental */ diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index 6c6640cbf34..83c64213c5b 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -164,6 +164,7 @@ export class ManagedResource { export class Subpass { readonly rasterViews: Map = new Map(); readonly computeViews: Map = new Map(); + readonly resolvePairs: ResolvePair[] = []; } //================================================================= diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index 05120880f29..d09e3b8a9fe 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -169,7 +169,7 @@ export enum ResourceFlags { INPUT_ATTACHMENT = 0x40, SHADING_RATE = 0x80, TRANSFER_SRC = 0x100, - TRANSFER_DST = 0x200 + TRANSFER_DST = 0x200, } export enum TaskType { diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 8f5d97636ab..23fdda466bc 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -179,6 +179,7 @@ PersistentRenderPassAndFramebuffer createPersistentRenderPassAndFramebuffer( PmrFlatSet set(scratch); auto fillFrameBufferInfo = [&](const ccstd::vector& passViews, bool hasResolve) { + std::ignore = hasResolve; const auto& uberPass = pass; auto numTotalAttachments = static_cast(passViews.size()); diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 69932c1ca75..4b3961fdbd6 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -654,6 +654,180 @@ void NativePipeline::addMovePass(const ccstd::vector &movePairs) { renderGraph); } +namespace { + +void setupGpuDrivenResources( + NativePipeline& ppl, uint32_t cullingID, ResourceGraph& resg, const std::string &hzbName) { + ccstd::pmr::string name(resg.get_allocator()); + { // init resource + name = "_GpuInit"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = addVertex( + PersistentBufferTag{}, + std::forward_as_tuple(name.c_str()), + std::forward_as_tuple(), + std::forward_as_tuple(ResourceTraits{ResourceResidency::EXTERNAL}), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(/*xxx*/), + resg); + } else { + CC_EXPECTS(holds(resID, resg)); + // get(PersistentBufferTag{}, resID, resg) = xxx; + } + } + { + name = "CCObjectBuffer"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, 0, ResourceResidency::MANAGED); + } else { + CC_EXPECTS(holds(resID, resg)); + ppl.updateStorageBuffer(std::string(name), 0, gfx::Format::UNKNOWN); + } + } + { + name = "CCInstanceBuffer"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, 0, ResourceResidency::MANAGED); + } else { + CC_EXPECTS(holds(resID, resg)); + ppl.updateStorageBuffer(std::string(name), 0, gfx::Format::UNKNOWN); + } + } + { + name = "CCDrawIndirectBuffer"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, 0, ResourceResidency::MANAGED); + } else { + CC_EXPECTS(holds(resID, resg)); + ppl.updateStorageBuffer(std::string(name), 0, gfx::Format::UNKNOWN); + } + } + { + name = "CCDrawInstanceBuffer"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, 0, ResourceResidency::MANAGED); + } else { + CC_EXPECTS(holds(resID, resg)); + ppl.updateStorageBuffer(std::string(name), 0, gfx::Format::UNKNOWN); + } + } + { + name = "CCVisibilityBuffer"; + name.append(std::to_string(cullingID)); + auto resID = findVertex(name, resg); + if (resID == ResourceGraph::null_vertex()) { + resID = ppl.addStorageBuffer(std::string(name), gfx::Format::UNKNOWN, 0, ResourceResidency::MANAGED); + } else { + CC_EXPECTS(holds(resID, resg)); + ppl.updateStorageBuffer(std::string(name), 0, gfx::Format::UNKNOWN); + } + } + if (!hzbName.empty()) { + + } +} + +} // namespace + +void NativePipeline::addBuiltinGpuCullingPass( + const scene::Camera *camera, const std::string &hzbName, const scene::Light *light) { + std::ignore = camera; + const uint32_t cullingID = ++nativeContext.sceneCulling.gpuCullingPassID; + setupGpuDrivenResources(*this, cullingID, resourceGraph, hzbName); + + if (light) { + // build light culling pass + return; + } + + const std::string objectBuffer = "CCObjectBuffer" + std::to_string(cullingID); + const std::string instanceBuffer = "CCInstanceBuffer" + std::to_string(cullingID); + const std::string drawIndirectBuffer = "CCDrawIndirectBuffer" + std::to_string(cullingID); + const std::string drawInstanceBuffer = "CCDrawInstanceBuffer" + std::to_string(cullingID); + const std::string visibilityBuffer = "CCVisibilityBuffer" + std::to_string(cullingID); + + // init indirected buffers + { + CopyPass copyPass{renderGraph.get_allocator()}; + { + CopyPair copyPair{renderGraph.get_allocator()}; + copyPair.source = "xxx"; + copyPair.target = drawIndirectBuffer; + copyPair.mipLevels = 1; + copyPair.numSlices = 1; + copyPass.copyPairs.emplace_back(std::move(copyPair)); + } + + auto copyID = addVertex2(CopyTag{}, + std::forward_as_tuple("CopyInitialIndirectBuffer"), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(copyPass)), + renderGraph); + CC_ENSURES(copyID != RenderGraph::null_vertex()); + } + // run compute cullling pass + { + ComputePass computePass{renderGraph.get_allocator()}; + { + auto res = computePass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(drawIndirectBuffer), + std::forward_as_tuple()); + auto& view = res.first->second.emplace_back(); + view.name = "CCDrawIndirectBuffer"; + view.accessType = AccessType::WRITE; + view.shaderStageFlags = gfx::ShaderStageFlagBit::COMPUTE; + } + { + auto res = computePass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(drawInstanceBuffer), + std::forward_as_tuple()); + auto& view = res.first->second.emplace_back(); + view.name = "CCDrawInstanceBuffer"; + view.accessType = AccessType::WRITE; + view.shaderStageFlags = gfx::ShaderStageFlagBit::COMPUTE; + } + { + auto res = computePass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(visibilityBuffer), + std::forward_as_tuple()); + auto& view = res.first->second.emplace_back(); + view.name = "CCVisibilityBuffer"; + view.accessType = AccessType::WRITE; + view.shaderStageFlags = gfx::ShaderStageFlagBit::COMPUTE; + } + + auto computePassID = addVertex2(ComputeTag{}, + std::forward_as_tuple("Scene"), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(), + std::forward_as_tuple(std::move(computePass)), + renderGraph); + CC_ENSURES(computePassID != RenderGraph::null_vertex()); + } +} + +void NativePipeline::addBuiltinHzbGenerationPass( + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + const std::string &sourceDepthStencilName, const std::string &targetHzbName) { +} + void NativePipeline::addCopyPass(const ccstd::vector ©Pairs) { CopyPass pass(renderGraph.get_allocator()); pass.copyPairs.reserve(copyPairs.size()); diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp index cf5285f441e..8ac8712164c 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp @@ -186,7 +186,8 @@ SceneCulling::SceneCulling(SceneCulling&& rhs, const allocator_type& alloc) renderQueues(std::move(rhs.renderQueues), alloc), sceneQueryIndex(std::move(rhs.sceneQueryIndex), alloc), numCullingQueries(rhs.numCullingQueries), - numRenderQueues(rhs.numRenderQueues) {} + numRenderQueues(rhs.numRenderQueues), + gpuCullingPassID(rhs.gpuCullingPassID) {} NativeRenderContext::NativeRenderContext(std::unique_ptr defaultResourceIn, const allocator_type& alloc) noexcept : defaultResource(std::move(defaultResourceIn)), diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index 11597dd0ab7..a1249c278ce 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -1144,6 +1144,7 @@ struct SceneCulling { PmrFlatMap sceneQueryIndex; uint32_t numCullingQueries{0}; uint32_t numRenderQueues{0}; + uint32_t gpuCullingPassID{0xFFFFFFFF}; }; struct NativeRenderContext { @@ -1305,6 +1306,8 @@ class NativePipeline final : public Pipeline { ComputePassBuilder *addComputePass(const ccstd::string &passName) override; void addUploadPass(ccstd::vector &uploadPairs) override; void addMovePass(const ccstd::vector &movePairs) override; + void addBuiltinGpuCullingPass(const scene::Camera *camera, const std::string &hzbName, const scene::Light *light) override; + void addBuiltinHzbGenerationPass(const std::string &sourceDepthStencilName, const std::string &targetHzbName) override; uint32_t addCustomBuffer(const ccstd::string &name, const gfx::BufferInfo &info, const std::string &type) override; uint32_t addCustomTexture(const ccstd::string &name, const gfx::TextureInfo &info, const std::string &type) override; diff --git a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp index ccc608966be..528c95d5ce7 100644 --- a/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeRenderGraph.cpp @@ -47,6 +47,17 @@ void NativeRenderNode::setCustomBehavior(const ccstd::string &name) { // NOLINT( get(RenderGraph::DataTag{}, *renderGraph, nodeID).custom = std::string_view{name}; } +RenderGraph::vertex_descriptor RenderGraph::getPassID(vertex_descriptor nodeID) const { + CC_EXPECTS(nodeID != null_vertex()); + for (auto parentID = nodeID; + parentID != RenderGraph::null_vertex(); + parentID = parent(nodeID, *this)) { + nodeID = parentID; + } + CC_ENSURES(nodeID != null_vertex()); + return nodeID; +} + namespace { template @@ -721,6 +732,42 @@ void NativeRenderQueueBuilder::addScene(const scene::Camera *camera, SceneFlags std::forward_as_tuple(std::move(data)), *renderGraph, nodeID); CC_ENSURES(sceneID != RenderGraph::null_vertex()); + + if (any(sceneFlags & SceneFlags::GPU_DRIVEN)) { + const auto passID = renderGraph->getPassID(nodeID); + const auto cullingID = dynamic_cast(pipelineRuntime)->nativeContext.sceneCulling.gpuCullingPassID; + CC_EXPECTS(cullingID != 0xFFFFFFFF); + if (holds(passID, *renderGraph)) { + ccstd::pmr::string drawIndirectBuffer("CCDrawIndirectBuffer"); + drawIndirectBuffer.append(std::to_string(cullingID)); + ccstd::pmr::string drawInstanceBuffer("CCDrawInstanceBuffer"); + drawInstanceBuffer.append(std::to_string(cullingID)); + + auto& rasterPass = get(RasterPassTag{}, passID, *renderGraph); + if (rasterPass.computeViews.find(drawIndirectBuffer) != rasterPass.computeViews.end()) { + auto res = rasterPass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(drawIndirectBuffer), + std::forward_as_tuple()); + CC_ENSURES(res.second); + auto& view = res.first->second.emplace_back(); + view.name = "CCDrawIndirectBuffer"; + view.accessType = AccessType::READ; + view.shaderStageFlags = gfx::ShaderStageFlagBit::VERTEX | gfx::ShaderStageFlagBit::FRAGMENT; + } + if (rasterPass.computeViews.find(drawInstanceBuffer) != rasterPass.computeViews.end()) { + auto res = rasterPass.computeViews.emplace( + std::piecewise_construct, + std::forward_as_tuple(drawInstanceBuffer), + std::forward_as_tuple()); + CC_ENSURES(res.second); + auto& view = res.first->second.emplace_back(); + view.name = "CCDrawInstanceBuffer"; + view.accessType = AccessType::READ; + view.shaderStageFlags = gfx::ShaderStageFlagBit::VERTEX | gfx::ShaderStageFlagBit::FRAGMENT; + } + } + } } void NativeRenderQueueBuilder::addSceneCulledByDirectionalLight( diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index 77d8b9c0b16..eb6dfe6a9b3 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -103,7 +103,7 @@ enum class ResourceFlags : uint32_t { INPUT_ATTACHMENT = 0x40, SHADING_RATE = 0x80, TRANSFER_SRC = 0x100, - TRANSFER_DST = 0x200 + TRANSFER_DST = 0x200, }; constexpr ResourceFlags operator|(const ResourceFlags lhs, const ResourceFlags rhs) noexcept { diff --git a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h index 0e2ac6e971c..acf43826fd8 100644 --- a/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderGraphTypes.h @@ -1048,6 +1048,7 @@ struct RenderGraph { impl::ValueHandle, impl::ValueHandle>; + vertex_descriptor getPassID(vertex_descriptor nodeID) const; ccstd::string print(boost::container::pmr::memory_resource* scratch) const; // ContinuousContainer diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index aa028273cd8..85d2b9cc03c 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -1478,6 +1478,8 @@ class Pipeline : public BasicPipeline { * @param movePairs @en Array of move source and target @zh 移动来源与目标的数组 */ virtual void addMovePass(const ccstd::vector &movePairs) = 0; + virtual void addBuiltinGpuCullingPass(const scene::Camera *camera, const std::string &hzbName, const scene::Light *light) = 0; + virtual void addBuiltinHzbGenerationPass(const std::string &sourceDepthStencilName, const std::string &targetHzbName) = 0; /** * @experimental */ @@ -1501,6 +1503,12 @@ class Pipeline : public BasicPipeline { void updateStorageTexture(const ccstd::string &name, uint32_t width, uint32_t height) { updateStorageTexture(name, width, height, gfx::Format::UNKNOWN); } + void addBuiltinGpuCullingPass(const scene::Camera *camera) { + addBuiltinGpuCullingPass(camera, "", nullptr); + } + void addBuiltinGpuCullingPass(const scene::Camera *camera, const std::string &hzbName) { + addBuiltinGpuCullingPass(camera, hzbName, nullptr); + } }; /** From 6a63d93fdc55456dd62e5ddc08a0cd738eb31001 Mon Sep 17 00:00:00 2001 From: Zach Lee Date: Wed, 12 Jul 2023 15:47:21 +0800 Subject: [PATCH 46/57] fix gles3 msaa with hardware buffer. (#150) --- native/cocos/renderer/gfx-base/GFXTexture.cpp | 4 ++-- .../renderer/gfx-gles3/GLES3Commands.cpp | 19 +++++++++++-------- .../renderer/gfx-gles3/GLES3GPUObjects.h | 1 - .../cocos/renderer/gfx-gles3/GLES3Texture.cpp | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/native/cocos/renderer/gfx-base/GFXTexture.cpp b/native/cocos/renderer/gfx-base/GFXTexture.cpp index 36845612a6d..0f1a7c2c14d 100644 --- a/native/cocos/renderer/gfx-base/GFXTexture.cpp +++ b/native/cocos/renderer/gfx-base/GFXTexture.cpp @@ -130,9 +130,9 @@ void Texture::updateTextureInfo(const SwapchainTextureInfo &info, Texture *out) out->_info.depth = 1; out->_info.samples = SampleCount::X1; out->_info.flags = TextureFlagBit::NONE; - out->_info.usage = GFX_FORMAT_INFOS[toNumber(info.format)].hasDepth + out->_info.usage = TextureUsageBit::SAMPLED | (GFX_FORMAT_INFOS[toNumber(info.format)].hasDepth ? TextureUsageBit::DEPTH_STENCIL_ATTACHMENT - : TextureUsageBit::COLOR_ATTACHMENT; + : TextureUsageBit::COLOR_ATTACHMENT); out->_swapchain = info.swapchain; out->_size = formatSize(info.format, info.width, info.height, 1); out->_hash = computeHash(out); diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index e54c79885d4..27cb55702bd 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -861,13 +861,12 @@ void cmdFuncGLES3CreateTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) gpuTexture->glInternalFmt = mapGLInternalFormat(gpuTexture->format); gpuTexture->glFormat = mapGLFormat(gpuTexture->format); gpuTexture->glType = formatToGLType(gpuTexture->format); - gpuTexture->glSamples = static_cast(gpuTexture->samples); bool supportRenderBufferMS = device->constantRegistry()->mMSRT > MSRTSupportLevel::NONE; gpuTexture->useRenderBuffer = useRenderBuffer(device, gpuTexture->format, gpuTexture->usage) && - (gpuTexture->samples <= SampleCount::X1 || supportRenderBufferMS); + (gpuTexture->glSamples <= 1 || supportRenderBufferMS); - if (gpuTexture->samples > SampleCount::X1) { + if (gpuTexture->glSamples > 1) { // Allocate render buffer when binding a framebuffer if the MSRT extension is not present. if (gpuTexture->useRenderBuffer && hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED)) { @@ -1576,7 +1575,7 @@ void cmdFuncGLES3CreateFramebuffer(GLES3Device *device, GLES3GPUFramebuffer *gpu CC_ASSERT(view != nullptr); // need to resolve - if (view->gpuTexture->glSamples != 1 && resolveIndex != INVALID_BINDING) { + if (view->gpuTexture->glSamples > 1 && resolveIndex != INVALID_BINDING) { const auto &resolveDesc = renderPass->colorAttachments[resolveIndex]; const auto *resolveView = gpuFBO->gpuColorViews[resolveIndex]; CC_ASSERT(resolveView != nullptr); @@ -1602,7 +1601,7 @@ void cmdFuncGLES3CreateFramebuffer(GLES3Device *device, GLES3GPUFramebuffer *gpu const auto *view = gpuFBO->gpuDepthStencilView; CC_ASSERT(view != nullptr); - if (view->gpuTexture->glSamples != 1 && depthStencilResolve != INVALID_BINDING) { + if (view->gpuTexture->glSamples > 1 && depthStencilResolve != INVALID_BINDING) { const auto &resolveDesc = renderPass->depthStencilResolveAttachment; const auto *resolveView = gpuFBO->gpuDepthStencilResolveView; bool lazilyAllocated = hasFlag(view->gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED); @@ -3091,7 +3090,7 @@ void GLES3GPUFramebufferObject::finalize(GLES3GPUStateCache *cache) { drawBuffers[i] =att; auto *texture = view->gpuTexture; - if (samples != 1) { + if (samples > 1) { CC_ASSERT(view->gpuTexture->glTexture != 0); GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, att, @@ -3117,16 +3116,20 @@ void GLES3GPUFramebufferObject::finalize(GLES3GPUStateCache *cache) { const auto &[view, samples] = depthStencil; auto *texture = view->gpuTexture; - if (samples != 1) { + if (samples > 1) { CC_ASSERT(view->gpuTexture->glTexture != 0); GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, dsAttachment, - texture->glTexture, + GL_TEXTURE_2D, view->gpuTexture->glTexture, view->baseLevel, static_cast(samples))); } else { if (texture->useRenderBuffer) { + if (view->gpuTexture->glRenderbuffer == 0) { + GL_CHECK(glGenRenderbuffers(1, &view->gpuTexture->glRenderbuffer)); + renderBufferStorage(GLES3Device::getInstance(), texture); + } GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glRenderbuffer)); } else { GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glTexture, view->baseLevel)); diff --git a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h index fa10675a6e8..da48024a362 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h +++ b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h @@ -130,7 +130,6 @@ struct GLES3GPUTexture { uint32_t size{0}; uint32_t arrayLayer{1}; uint32_t mipLevel{1}; - SampleCount samples{SampleCount::X1}; TextureFlags flags{TextureFlagBit::NONE}; bool immutable{true}; bool isPowerOf2{false}; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp index f5fc08157d6..ff8dc88350f 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp @@ -52,7 +52,7 @@ void GLES3Texture::doInit(const TextureInfo & /*info*/) { _gpuTexture->depth = _info.depth; _gpuTexture->arrayLayer = _info.layerCount; _gpuTexture->mipLevel = _info.levelCount; - _gpuTexture->samples = _info.samples; + _gpuTexture->glSamples = static_cast(_info.samples); _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; _gpuTexture->isPowerOf2 = math::isPowerOfTwo(_info.width) && math::isPowerOfTwo(_info.height); @@ -164,7 +164,7 @@ void GLES3Texture::doInit(const SwapchainTextureInfo & /*info*/) { _gpuTexture->depth = _info.depth; _gpuTexture->arrayLayer = _info.layerCount; _gpuTexture->mipLevel = _info.levelCount; - _gpuTexture->samples = _info.samples; + _gpuTexture->glSamples = static_cast(_info.samples); _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; _gpuTexture->allocateMemory = false; From 551d0c5c74db687775b17c5af2d829f745cfe7f2 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Fri, 14 Jul 2023 16:47:01 +0800 Subject: [PATCH 47/57] fix various problems --- .../cocos/renderer/gfx-base/GFXDef-common.h | 3 ++- native/cocos/renderer/gfx-metal/MTLDevice.h | 2 +- native/cocos/renderer/gfx-metal/MTLDevice.mm | 4 ++-- .../pipeline/custom/NativeBuiltinUtils.cpp | 24 +++++++++++++++++++ .../pipeline/custom/NativeBuiltinUtils.h | 24 +++++++++++++++++++ .../renderer/pipeline/custom/NativeSetter.cpp | 24 +++++++++++++++++++ .../renderer/pipeline/custom/NativeUtils.cpp | 24 +++++++++++++++++++ .../renderer/pipeline/custom/NativeUtils.h | 24 +++++++++++++++++++ 8 files changed, 125 insertions(+), 4 deletions(-) diff --git a/native/cocos/renderer/gfx-base/GFXDef-common.h b/native/cocos/renderer/gfx-base/GFXDef-common.h index f82b5604df8..ab5c7bd810f 100644 --- a/native/cocos/renderer/gfx-base/GFXDef-common.h +++ b/native/cocos/renderer/gfx-base/GFXDef-common.h @@ -173,8 +173,9 @@ enum class Feature : uint32_t { MULTIPLE_RENDER_TARGETS, BLEND_MINMAX, COMPUTE_SHADER, + // @deprecated + INPUT_ATTACHMENT_BENEFIT, - INPUT_ATTACHMENT_BENEFIT, // @deprecated SUBPASS_COLOR_INPUT, SUBPASS_DEPTH_STENCIL_INPUT, RASTERIZATION_ORDER_NOCOHERENT, diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.h b/native/cocos/renderer/gfx-metal/MTLDevice.h index e9cdecb3cf9..14064a3f308 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.h +++ b/native/cocos/renderer/gfx-metal/MTLDevice.h @@ -89,7 +89,7 @@ class CCMTLDevice final : public Device { } } - inline CCMTLGPUDeviceObject* gpuObject() { return _gpuDeviceObj; } + inline CCMTLGPUDeviceObject* gpuObject() const { return _gpuDeviceObj; } protected: static CCMTLDevice *_instance; diff --git a/native/cocos/renderer/gfx-metal/MTLDevice.mm b/native/cocos/renderer/gfx-metal/MTLDevice.mm index 5004befa238..186a152bcda 100644 --- a/native/cocos/renderer/gfx-metal/MTLDevice.mm +++ b/native/cocos/renderer/gfx-metal/MTLDevice.mm @@ -530,7 +530,7 @@ of this software and associated engine source code (the "Software"), a limited, } SampleCount CCMTLDevice::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const { - const SampleCount samples[] = { + const SampleCount sampleCounts[] = { SampleCount::X64, SampleCount::X32, SampleCount::X16, @@ -538,7 +538,7 @@ of this software and associated engine source code (the "Software"), a limited, SampleCount::X4, SampleCount::X2, }; - for (auto sampleCount : samples) { + for (auto sampleCount : sampleCounts) { if ([_mtlDevice supportsTextureSampleCount: static_cast(sampleCount)]) { return sampleCount; } diff --git a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp index 3172c80d969..07c7d0aaa33 100644 --- a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp @@ -1,3 +1,27 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + #include "NativeBuiltinUtils.h" #include "cocos/application/ApplicationManager.h" #include "cocos/renderer/gfx-base/GFXDef-common.h" diff --git a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h index 8e74ba1a4f3..b123a5332ac 100644 --- a/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.h @@ -1,3 +1,27 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + #pragma once #include #include "cocos/renderer/pipeline/custom/LayoutGraphFwd.h" diff --git a/native/cocos/renderer/pipeline/custom/NativeSetter.cpp b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp index b7951a7c869..6f4e2ca6fd9 100644 --- a/native/cocos/renderer/pipeline/custom/NativeSetter.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeSetter.cpp @@ -1,3 +1,27 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + #include "cocos/renderer/pipeline/custom/NativeBuiltinUtils.h" #include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" #include "cocos/renderer/pipeline/custom/NativeUtils.h" diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp index 480ade58e1d..4edad502350 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.cpp @@ -1,3 +1,27 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + #include "cocos/renderer/pipeline/custom/NativeUtils.h" #include "cocos/renderer/pipeline/custom/LayoutGraphGraphs.h" #include "cocos/renderer/pipeline/custom/NativePipelineTypes.h" diff --git a/native/cocos/renderer/pipeline/custom/NativeUtils.h b/native/cocos/renderer/pipeline/custom/NativeUtils.h index 7e0a17834ec..82595dc3c92 100644 --- a/native/cocos/renderer/pipeline/custom/NativeUtils.h +++ b/native/cocos/renderer/pipeline/custom/NativeUtils.h @@ -1,3 +1,27 @@ +/**************************************************************************** + Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. + + http://www.cocos.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +****************************************************************************/ + #pragma once #include "cocos/core/ArrayBuffer.h" #include "cocos/math/Vec4.h" From 275fe8fab28d6357a56e5f97019ee19134056b2e Mon Sep 17 00:00:00 2001 From: Zach Lee Date: Fri, 14 Jul 2023 17:27:02 +0800 Subject: [PATCH 48/57] update gles3 framebuffer attachent binding && add comment. (#151) * update gles3 framebuffer attachent binding && add comment. * rename allocateMemory to memoryAllocated. --- .../renderer/gfx-gles2/GLES2Commands.cpp | 4 +- .../renderer/gfx-gles2/GLES2GPUObjects.h | 2 +- .../cocos/renderer/gfx-gles2/GLES2Texture.cpp | 10 +-- .../renderer/gfx-gles3/GLES3Commands.cpp | 63 ++++++++----------- .../renderer/gfx-gles3/GLES3GPUObjects.h | 2 +- .../cocos/renderer/gfx-gles3/GLES3Texture.cpp | 10 +-- .../cocos/renderer/gfx-vulkan/VKCommands.cpp | 6 +- .../cocos/renderer/gfx-vulkan/VKGPUObjects.h | 2 +- .../cocos/renderer/gfx-vulkan/VKTexture.cpp | 6 +- 9 files changed, 46 insertions(+), 59 deletions(-) diff --git a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp index bf5895a2b3b..1d9ca68f441 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp @@ -579,7 +579,7 @@ void cmdFuncGLES2CreateTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture) if (gpuTexture->samples > SampleCount::X1) { if (device->constantRegistry()->mMSRT != MSRTSupportLevel::NONE && hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED)) { - gpuTexture->allocateMemory = false; + gpuTexture->memoryAllocated = false; return; } } @@ -801,7 +801,7 @@ void cmdFuncGLES2DestroyTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture } void cmdFuncGLES2ResizeTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture) { - if (!gpuTexture->allocateMemory || gpuTexture->glTarget == GL_TEXTURE_EXTERNAL_OES) return; + if (!gpuTexture->memoryAllocated || gpuTexture->glTarget == GL_TEXTURE_EXTERNAL_OES) return; if (gpuTexture->glSamples <= 1) { switch (gpuTexture->type) { diff --git a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h index 7b252b240d0..99ce522f08d 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h +++ b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h @@ -121,7 +121,7 @@ struct GLES2GPUTexture { SampleCount samples{SampleCount::X1}; TextureFlags flags{TextureFlagBit::NONE}; bool isPowerOf2{false}; - bool allocateMemory{true}; // false if swapchain image or implicit ms render buffer. + bool memoryAllocated{true}; // false if swapchain image or implicit ms render buffer. GLenum glTarget{0}; GLenum glInternalFmt{0}; GLenum glFormat{0}; diff --git a/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp b/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp index bfb6cc21809..2656dff1b46 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Texture.cpp @@ -59,7 +59,7 @@ void GLES2Texture::doInit(const TextureInfo & /*info*/) { cmdFuncGLES2CreateTexture(GLES2Device::getInstance(), _gpuTexture); - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES2Device::getInstance()->getMemoryStatus().textureSize += _size; CC_PROFILE_MEMORY_INC(Texture, _size); } @@ -72,7 +72,7 @@ void GLES2Texture::doInit(const TextureViewInfo &info) { void GLES2Texture::doDestroy() { if (_gpuTexture) { if (!_isTextureView) { - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -85,7 +85,7 @@ void GLES2Texture::doDestroy() { } void GLES2Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -97,7 +97,7 @@ void GLES2Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { GLES2Device::getInstance()->framebufferHub()->update(_gpuTexture); - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES2Device::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } @@ -135,7 +135,7 @@ void GLES2Texture::doInit(const SwapchainTextureInfo & /*info*/) { _gpuTexture->samples = _info.samples; _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; - _gpuTexture->allocateMemory = false; + _gpuTexture->memoryAllocated = false; _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); } diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index 6e832cd894a..afddfc2d1a7 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -871,7 +871,7 @@ void cmdFuncGLES3CreateTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) if (gpuTexture->useRenderBuffer && hasFlag(gpuTexture->flags, TextureFlagBit::LAZILY_ALLOCATED)) { gpuTexture->glTarget = GL_RENDERBUFFER; - gpuTexture->allocateMemory = false; + gpuTexture->memoryAllocated = false; return; } } @@ -925,7 +925,7 @@ void cmdFuncGLES3DestroyTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture } void cmdFuncGLES3ResizeTexture(GLES3Device *device, GLES3GPUTexture *gpuTexture) { - if (!gpuTexture->allocateMemory || + if (!gpuTexture->memoryAllocated || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_NORMAL)) { return; @@ -2634,7 +2634,7 @@ uint8_t *funcGLES3PixelBufferPick(const uint8_t *buffer, Format format, uint32_t } void cmdFuncGLES3CopyBuffersToTexture(GLES3Device *device, const uint8_t *const *buffers, GLES3GPUTexture *gpuTexture, const BufferTextureCopy *regions, uint32_t count) { - if (!gpuTexture->allocateMemory) return; + if (!gpuTexture->memoryAllocated) return; GLuint &glTexture = device->stateCache()->glTextures[device->stateCache()->texUint]; if (glTexture != gpuTexture->glTexture) { @@ -3082,58 +3082,45 @@ void GLES3GPUFramebufferObject::finalize(GLES3GPUStateCache *cache) { GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, handle)); cache->glDrawFramebuffer = handle; - ccstd::vector drawBuffers(colors.size(), GL_NONE); - for (uint32_t i = 0; i < colors.size(); ++i) { - const auto &[view, samples] = colors[i]; - auto att = static_cast(GL_COLOR_ATTACHMENT0 + i); - drawBuffers[i] =att; - + auto bindAttachment = [](GLenum attachment, GLint samples, const GLES3GPUTextureView *view) { auto *texture = view->gpuTexture; if (samples > 1) { CC_ASSERT(view->gpuTexture->glTexture != 0); GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, - att, - GL_TEXTURE_2D, - texture->glTexture, - view->baseLevel, - static_cast(samples))); - continue; + attachment, + GL_TEXTURE_2D, + texture->glTexture, + view->baseLevel, + static_cast(samples))); + return; } if (texture->useRenderBuffer) { + /* + * Renderbuffer is not allocated if using lazily allocated flag. + * If the attachment does not meet the implicit MS condition, renderbuffer should be allocated here. + */ if (view->gpuTexture->glRenderbuffer == 0) { GL_CHECK(glGenRenderbuffers(1, &view->gpuTexture->glRenderbuffer)); renderBufferStorage(GLES3Device::getInstance(), texture); } - GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, att, texture->glTarget, texture->glRenderbuffer)); + GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, attachment, texture->glTarget, texture->glRenderbuffer)); } else { - GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, att, texture->glTarget, texture->glTexture, view->baseLevel)); + GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, texture->glTarget, texture->glTexture, view->baseLevel)); } + }; + + ccstd::vector drawBuffers(colors.size(), GL_NONE); + for (uint32_t i = 0; i < colors.size(); ++i) { + const auto &[view, samples] = colors[i]; + auto att = static_cast(GL_COLOR_ATTACHMENT0 + i); + drawBuffers[i] = att; + bindAttachment(att, samples, view); } if (depthStencil.first != nullptr) { const auto &[view, samples] = depthStencil; - - auto *texture = view->gpuTexture; - if (samples > 1) { - CC_ASSERT(view->gpuTexture->glTexture != 0); - GL_CHECK(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, - dsAttachment, - GL_TEXTURE_2D, - view->gpuTexture->glTexture, - view->baseLevel, - static_cast(samples))); - } else { - if (texture->useRenderBuffer) { - if (view->gpuTexture->glRenderbuffer == 0) { - GL_CHECK(glGenRenderbuffers(1, &view->gpuTexture->glRenderbuffer)); - renderBufferStorage(GLES3Device::getInstance(), texture); - } - GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glRenderbuffer)); - } else { - GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, dsAttachment, texture->glTarget, texture->glTexture, view->baseLevel)); - } - } + bindAttachment(dsAttachment, samples, view); } if (!drawBuffers.empty()) { diff --git a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h index da48024a362..169767fe082 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h +++ b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h @@ -134,7 +134,7 @@ struct GLES3GPUTexture { bool immutable{true}; bool isPowerOf2{false}; bool useRenderBuffer{false}; - bool allocateMemory{true}; // false if swapchain image or implicit ms render buffer. + bool memoryAllocated{true}; // false if swapchain image or implicit ms render buffer. GLenum glTarget{0}; GLenum glInternalFmt{0}; GLenum glFormat{0}; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp index ff8dc88350f..286ef62b78f 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Texture.cpp @@ -71,7 +71,7 @@ void GLES3Texture::doInit(const TextureInfo & /*info*/) { cmdFuncGLES3CreateTexture(GLES3Device::getInstance(), _gpuTexture); - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES3Device::getInstance()->getMemoryStatus().textureSize += _size; CC_PROFILE_MEMORY_INC(Texture, _size); } @@ -101,7 +101,7 @@ void GLES3Texture::doDestroy() { CC_SAFE_DELETE(_gpuTextureView); if (_gpuTexture) { if (!_isTextureView) { - if (_gpuTexture->allocateMemory) { + if (_gpuTexture->memoryAllocated) { GLES3Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -115,7 +115,7 @@ void GLES3Texture::doDestroy() { } void GLES3Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { - if (!_isTextureView && _gpuTexture->allocateMemory) { + if (!_isTextureView && _gpuTexture->memoryAllocated) { GLES3Device::getInstance()->getMemoryStatus().textureSize -= _size; CC_PROFILE_MEMORY_DEC(Texture, _size); } @@ -129,7 +129,7 @@ void GLES3Texture::doResize(uint32_t width, uint32_t height, uint32_t size) { GLES3Device::getInstance()->framebufferHub()->update(_gpuTexture); - if (!_isTextureView && _gpuTexture->allocateMemory) { + if (!_isTextureView && _gpuTexture->memoryAllocated) { GLES3Device::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } @@ -167,7 +167,7 @@ void GLES3Texture::doInit(const SwapchainTextureInfo & /*info*/) { _gpuTexture->glSamples = static_cast(_info.samples); _gpuTexture->flags = _info.flags; _gpuTexture->size = _size; - _gpuTexture->allocateMemory = false; + _gpuTexture->memoryAllocated = false; _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); _gpuTextureView = ccnew GLES3GPUTextureView; createTextureView(); diff --git a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp index e3069085a6e..cf098298382 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp @@ -158,7 +158,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { VkResult result = vmaCreateImage(device->gpuDevice()->memoryAllocator, &createInfo, &allocInfo, pVkImage, pVmaAllocation, &res); if (!result) { - gpuTexture->allocateMemory = false; + gpuTexture->memoryAllocated = false; return; } @@ -166,7 +166,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; } - gpuTexture->allocateMemory = true; + gpuTexture->memoryAllocated = true; VK_CHECK(vmaCreateImage(device->gpuDevice()->memoryAllocator, &createInfo, &allocInfo, pVkImage, pVmaAllocation, &res)); }; @@ -184,7 +184,7 @@ void cmdFuncCCVKCreateTexture(CCVKDevice *device, CCVKGPUTexture *gpuTexture) { gpuTexture->swapchainVkImages[i] = gpuTexture->swapchain->swapchainImages[i]; } } - gpuTexture->allocateMemory = false; + gpuTexture->memoryAllocated = false; } else if (hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) || hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_NORMAL)) { gpuTexture->vkImage = gpuTexture->externalVKImage; } else { diff --git a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h index 02d77f4a581..cb386223c67 100644 --- a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h +++ b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h @@ -159,7 +159,7 @@ struct CCVKGPUTexture : public CCVKGPUDeviceObject { * 3. Memory bound manually bound. * 4. Sparse Image. */ - bool allocateMemory = true; + bool memoryAllocated = true; VkImage vkImage = VK_NULL_HANDLE; VmaAllocation vmaAllocation = VK_NULL_HANDLE; diff --git a/native/cocos/renderer/gfx-vulkan/VKTexture.cpp b/native/cocos/renderer/gfx-vulkan/VKTexture.cpp index ccb83024090..5f0a3e85b47 100644 --- a/native/cocos/renderer/gfx-vulkan/VKTexture.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKTexture.cpp @@ -60,7 +60,7 @@ void CCVKTexture::createTexture(uint32_t width, uint32_t height, uint32_t size, if (_swapchain != nullptr) { _gpuTexture->swapchain = static_cast(_swapchain)->gpuSwapchain(); - _gpuTexture->allocateMemory = false; + _gpuTexture->memoryAllocated = false; } _gpuTexture->type = _info.type; @@ -121,14 +121,14 @@ void CCVKTexture::doInit(const SwapchainTextureInfo & /*info*/) { void CCVKGPUTexture::init() { cmdFuncCCVKCreateTexture(CCVKDevice::getInstance(), this); - if (allocateMemory) { + if (memoryAllocated) { CCVKDevice::getInstance()->getMemoryStatus().textureSize += size; CC_PROFILE_MEMORY_INC(Texture, size); } } void CCVKGPUTexture::shutdown() { - if (allocateMemory) { + if (memoryAllocated) { CCVKDevice::getInstance()->getMemoryStatus().textureSize -= size; CC_PROFILE_MEMORY_DEC(Texture, size); } From 46e8e8f489826fbb35b823e623de9fc094ae579b Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Mon, 17 Jul 2023 14:00:58 +0800 Subject: [PATCH 49/57] remove Scene from interface --- cocos/rendering/custom/executor.ts | 3 +- cocos/rendering/custom/pipeline.ts | 36 +----------- cocos/rendering/custom/scene.ts | 34 ++++++++++++ cocos/rendering/custom/web-scene-visitor.ts | 2 +- cocos/rendering/custom/web-scene.ts | 2 +- native/CMakeLists.txt | 1 - .../pipeline/custom/NativeDefaultScene.cpp | 50 ----------------- .../pipeline/custom/NativePipeline.cpp | 5 -- .../pipeline/custom/NativePipelineFwd.h | 3 - .../pipeline/custom/NativePipelineTypes.cpp | 6 -- .../pipeline/custom/NativePipelineTypes.h | 48 ---------------- .../pipeline/custom/RenderInterfaceFwd.h | 3 - .../pipeline/custom/RenderInterfaceTypes.h | 55 ------------------- native/tools/swig-config/render.i | 4 -- 14 files changed, 40 insertions(+), 212 deletions(-) create mode 100644 cocos/rendering/custom/scene.ts delete mode 100644 native/cocos/renderer/pipeline/custom/NativeDefaultScene.cpp diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index d2971497af6..b699cd72035 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -78,7 +78,8 @@ import { IRenderPass, isEnableEffect, SetIndex, UBODeferredLight, UBOForwardLigh import { PipelineSceneData } from '../pipeline-scene-data'; import { PipelineInputAssemblerData } from '../render-pipeline'; import { DescriptorSetData, LayoutGraphData, PipelineLayoutData, RenderPhaseData, RenderStageData } from './layout-graph'; -import { BasicPipeline, SceneVisitor } from './pipeline'; +import { BasicPipeline } from './pipeline'; +import { SceneVisitor } from './scene'; import { Blit, ClearView, diff --git a/cocos/rendering/custom/pipeline.ts b/cocos/rendering/custom/pipeline.ts index 3d151f338f6..c679c5796dd 100644 --- a/cocos/rendering/custom/pipeline.ts +++ b/cocos/rendering/custom/pipeline.ts @@ -32,12 +32,12 @@ import { Material } from '../../asset/assets'; import { Camera } from '../../render-scene/scene/camera'; import { DirectionalLight } from '../../render-scene/scene/directional-light'; import { GeometryRenderer } from '../geometry-renderer'; -import { Buffer, BufferInfo, ClearFlagBit, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, DrawInfo, Format, InputAssembler, LoadOp, PipelineState, Rect, ResolveMode, SampleCount, Sampler, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureInfo, Viewport } from '../../gfx'; +import { Buffer, BufferInfo, ClearFlagBit, Color, CommandBuffer, DescriptorSet, DescriptorSetLayout, Device, Format, LoadOp, ResolveMode, SampleCount, Sampler, ShaderStageFlagBit, StoreOp, Swapchain, Texture, TextureInfo, Viewport } from '../../gfx'; import { GlobalDSManager } from '../global-descriptor-set-manager'; import { Mat4, Quat, Vec2, Vec4 } from '../../core/math'; import { MacroRecord } from '../../render-scene/core/pass-utils'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, TaskType, UpdateFrequency, UploadPair } from './types'; +import { AccessType, CopyPair, LightInfo, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency, UploadPair } from './types'; import { RenderWindow } from '../../render-scene/core/render-window'; import { Light, Model } from '../../render-scene/scene'; import { SpotLight } from '../../render-scene/scene/spot-light'; @@ -1195,38 +1195,6 @@ export interface ComputePassBuilder extends Setter { setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void; } -/** - * @deprecated @en Not used @zh 未使用 - */ -export interface SceneVisitor { - readonly pipelineSceneData: PipelineSceneData; - setViewport (vp: Viewport): void; - setScissor (rect: Rect): void; - bindPipelineState (pso: PipelineState): void; - bindInputAssembler (ia: InputAssembler): void; - draw (info: DrawInfo): void; - - bindDescriptorSet (set: number, descriptorSet: DescriptorSet, dynamicOffsets?: number[]): void; - updateBuffer (buffer: Buffer, data: ArrayBuffer, size?: number): void; -} - -/** - * @deprecated @en Not used @zh 未使用 - */ -export interface SceneTask { - readonly taskType: TaskType; - start (): void; - join (): void; - submit (): void; -} - -/** - * @deprecated @en Not used @zh 未使用 - */ -export interface SceneTransversal { - transverse (visitor: SceneVisitor): SceneTask; -} - /** * @en Render pipeline. * @zh 渲染管线 diff --git a/cocos/rendering/custom/scene.ts b/cocos/rendering/custom/scene.ts new file mode 100644 index 00000000000..d46cf08a273 --- /dev/null +++ b/cocos/rendering/custom/scene.ts @@ -0,0 +1,34 @@ +import { + Buffer, + DescriptorSet, + DrawInfo, + InputAssembler, + PipelineState, + Rect, + Viewport, +} from '../../gfx'; +import { PipelineSceneData } from '../pipeline-scene-data'; +import { TaskType } from './types'; + +export interface SceneVisitor { + readonly pipelineSceneData: PipelineSceneData; + setViewport (vp: Viewport): void; + setScissor (rect: Rect): void; + bindPipelineState (pso: PipelineState): void; + bindInputAssembler (ia: InputAssembler): void; + draw (info: DrawInfo | InputAssembler): void; + + bindDescriptorSet (set: number, descriptorSet: DescriptorSet, dynamicOffsets?: number[]): void; + updateBuffer (buffer: Buffer, data: ArrayBuffer, size?: number): void; +} + +export interface SceneTask { + readonly taskType: TaskType; + start (): void; + join (): void; + submit (): void; +} + +export interface SceneTransversal { + transverse (visitor: SceneVisitor): SceneTask; +} diff --git a/cocos/rendering/custom/web-scene-visitor.ts b/cocos/rendering/custom/web-scene-visitor.ts index 81f3d187c15..a50cdb851e3 100644 --- a/cocos/rendering/custom/web-scene-visitor.ts +++ b/cocos/rendering/custom/web-scene-visitor.ts @@ -24,7 +24,7 @@ import { PipelineState, DescriptorSet, InputAssembler, DrawInfo, Buffer, CommandBuffer, Rect, Viewport } from '../../gfx'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { SceneVisitor } from './pipeline'; +import { SceneVisitor } from './scene'; export class WebSceneVisitor implements SceneVisitor { protected _pipelineSceneData: PipelineSceneData; diff --git a/cocos/rendering/custom/web-scene.ts b/cocos/rendering/custom/web-scene.ts index 7a4c6a6150f..ea0272151da 100644 --- a/cocos/rendering/custom/web-scene.ts +++ b/cocos/rendering/custom/web-scene.ts @@ -28,7 +28,7 @@ import { RenderScene, scene } from '../../render-scene'; import { Camera, Model, ShadowType, SKYBOX_FLAG } from '../../render-scene/scene'; import { IRenderObject, IRenderPass, UBOShadow } from '../define'; import { PipelineSceneData } from '../pipeline-scene-data'; -import { SceneTask, SceneTransversal, SceneVisitor } from './pipeline'; +import { SceneTask, SceneTransversal, SceneVisitor } from './scene'; import { TaskType } from './types'; import { PipelineUBO } from '../pipeline-ubo'; diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index d6247a45606..bf1218beb9c 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -1412,7 +1412,6 @@ cocos_source_files( cocos/renderer/pipeline/custom/LayoutGraphUtils.h cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp cocos/renderer/pipeline/custom/NativeBuiltinUtils.h - cocos/renderer/pipeline/custom/NativeDefaultScene.cpp cocos/renderer/pipeline/custom/NativeExecutor.cpp cocos/renderer/pipeline/custom/NativeFactory.cpp cocos/renderer/pipeline/custom/NativeFwd.h diff --git a/native/cocos/renderer/pipeline/custom/NativeDefaultScene.cpp b/native/cocos/renderer/pipeline/custom/NativeDefaultScene.cpp deleted file mode 100644 index 219ef6690e4..00000000000 --- a/native/cocos/renderer/pipeline/custom/NativeDefaultScene.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd. - - https://www.cocos.com/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -****************************************************************************/ - -#include "NativePipelineTypes.h" - -namespace cc { - -namespace render { - -const pipeline::PipelineSceneData *DefaultSceneVisitor::getPipelineSceneData() const { - return nullptr; -} - -void DefaultSceneVisitor::setViewport(const gfx::Viewport &vp) {} -void DefaultSceneVisitor::setScissor(const gfx::Rect &rect) {} -void DefaultSceneVisitor::bindPipelineState(gfx::PipelineState *pso) {} -void DefaultSceneVisitor::bindDescriptorSet(uint32_t set, gfx::DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) {} -void DefaultSceneVisitor::bindInputAssembler(gfx::InputAssembler *ia) {} -void DefaultSceneVisitor::updateBuffer(gfx::Buffer *buff, const void *data, uint32_t size) {} -void DefaultSceneVisitor::draw(const gfx::DrawInfo &info) {} - -SceneTask *DefaultForwardLightingTransversal::transverse(SceneVisitor *visitor) const { - std::ignore = visitor; - return nullptr; -} - -} // namespace render - -} // namespace cc diff --git a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp index 4b3961fdbd6..ff89a8cd6dc 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipeline.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipeline.cpp @@ -42,11 +42,6 @@ namespace cc { namespace render { -SceneTask *NativeSceneTransversal::transverse(SceneVisitor *visitor) const { - std::ignore = visitor; - return nullptr; -} - NativePipeline::NativePipeline(const allocator_type &alloc) noexcept : device(gfx::Device::getInstance()), globalDSManager(std::make_unique()), diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h index 71387358734..846d97ac32d 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h @@ -49,13 +49,10 @@ class NativeRenderPassBuilder; class NativeMultisampleRenderPassBuilder; class NativeComputeQueueBuilder; class NativeComputePassBuilder; -class NativeSceneTransversal; struct RenderInstancingQueue; struct DrawInstance; struct RenderDrawQueue; struct NativeRenderQueue; -class DefaultSceneVisitor; -class DefaultForwardLightingTransversal; struct ResourceGroup; struct BufferPool; struct DescriptorSetPool; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp index 8ac8712164c..d8de417ef46 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp @@ -80,12 +80,6 @@ NativeRenderQueue::NativeRenderQueue(NativeRenderQueue&& rhs, const allocator_ty sceneFlags(rhs.sceneFlags), subpassOrPassLayoutID(rhs.subpassOrPassLayoutID) {} -DefaultSceneVisitor::DefaultSceneVisitor(const allocator_type& alloc) noexcept -: name(alloc) {} - -DefaultForwardLightingTransversal::DefaultForwardLightingTransversal(const allocator_type& alloc) noexcept -: name(alloc) {} - ResourceGroup::ResourceGroup(const allocator_type& alloc) noexcept : instancingBuffers(alloc) {} diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index a1249c278ce..b21235bc46b 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -766,19 +766,6 @@ class NativeComputePassBuilder final : public ComputePassBuilder, public NativeS void setCustomShaderStages(const ccstd::string &name, gfx::ShaderStageFlagBit stageFlags) override; }; -class NativeSceneTransversal final : public SceneTransversal { -public: - NativeSceneTransversal() = default; - NativeSceneTransversal(const scene::Camera* cameraIn, const scene::RenderScene* sceneIn) noexcept - : camera(cameraIn), - scene(sceneIn) {} - - SceneTask *transverse(SceneVisitor *visitor) const override; - - const scene::Camera* camera{nullptr}; - const scene::RenderScene* scene{nullptr}; -}; - struct RenderInstancingQueue { using allocator_type = boost::container::pmr::polymorphic_allocator; allocator_type get_allocator() const noexcept { // NOLINT @@ -870,41 +857,6 @@ struct NativeRenderQueue { uint32_t subpassOrPassLayoutID{0xFFFFFFFF}; }; -class DefaultSceneVisitor final : public SceneVisitor { -public: - using allocator_type = boost::container::pmr::polymorphic_allocator; - allocator_type get_allocator() const noexcept { // NOLINT - return {name.get_allocator().resource()}; - } - - DefaultSceneVisitor(const allocator_type& alloc) noexcept; // NOLINT - - const pipeline::PipelineSceneData *getPipelineSceneData() const override; - void setViewport(const gfx::Viewport &vp) override; - void setScissor(const gfx::Rect &rect) override; - void bindPipelineState(gfx::PipelineState *pso) override; - void bindDescriptorSet(uint32_t set, gfx::DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) override; - void bindInputAssembler(gfx::InputAssembler *ia) override; - void updateBuffer(gfx::Buffer *buff, const void *data, uint32_t size) override; - void draw(const gfx::DrawInfo &info) override; - - ccstd::pmr::string name; -}; - -class DefaultForwardLightingTransversal final : public SceneTransversal { -public: - using allocator_type = boost::container::pmr::polymorphic_allocator; - allocator_type get_allocator() const noexcept { // NOLINT - return {name.get_allocator().resource()}; - } - - DefaultForwardLightingTransversal(const allocator_type& alloc) noexcept; // NOLINT - - SceneTask *transverse(SceneVisitor *visitor) const override; - - ccstd::pmr::string name; -}; - struct ResourceGroup { using allocator_type = boost::container::pmr::polymorphic_allocator; allocator_type get_allocator() const noexcept { // NOLINT diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h index 0bbcf866469..7a72a5f60e8 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceFwd.h @@ -58,9 +58,6 @@ class ComputeSubpassBuilder; class RenderPassBuilder; class MultisampleRenderPassBuilder; class ComputePassBuilder; -class SceneVisitor; -class SceneTask; -class SceneTransversal; class Pipeline; class PipelineBuilder; class RenderingModule; diff --git a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h index 85d2b9cc03c..4c5e015b567 100644 --- a/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderInterfaceTypes.h @@ -1310,61 +1310,6 @@ class ComputePassBuilder : public Setter { } }; -/** - * @deprecated @en Not used @zh 未使用 - */ -class SceneVisitor { -public: - SceneVisitor() noexcept = default; - SceneVisitor(SceneVisitor&& rhs) = delete; - SceneVisitor(SceneVisitor const& rhs) = delete; - SceneVisitor& operator=(SceneVisitor&& rhs) = delete; - SceneVisitor& operator=(SceneVisitor const& rhs) = delete; - virtual ~SceneVisitor() noexcept = default; - - virtual const pipeline::PipelineSceneData *getPipelineSceneData() const = 0; - virtual void setViewport(const gfx::Viewport &vp) = 0; - virtual void setScissor(const gfx::Rect &rect) = 0; - virtual void bindPipelineState(gfx::PipelineState *pso) = 0; - virtual void bindDescriptorSet(uint32_t set, gfx::DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) = 0; - virtual void bindInputAssembler(gfx::InputAssembler *ia) = 0; - virtual void updateBuffer(gfx::Buffer *buff, const void *data, uint32_t size) = 0; - virtual void draw(const gfx::DrawInfo &info) = 0; -}; - -/** - * @deprecated @en Not used @zh 未使用 - */ -class SceneTask { -public: - SceneTask() noexcept = default; - SceneTask(SceneTask&& rhs) = delete; - SceneTask(SceneTask const& rhs) = delete; - SceneTask& operator=(SceneTask&& rhs) = delete; - SceneTask& operator=(SceneTask const& rhs) = delete; - virtual ~SceneTask() noexcept = default; - - virtual TaskType getTaskType() const noexcept = 0; - virtual void start() = 0; - virtual void join() = 0; - virtual void submit() = 0; -}; - -/** - * @deprecated @en Not used @zh 未使用 - */ -class SceneTransversal { -public: - SceneTransversal() noexcept = default; - SceneTransversal(SceneTransversal&& rhs) = delete; - SceneTransversal(SceneTransversal const& rhs) = delete; - SceneTransversal& operator=(SceneTransversal&& rhs) = delete; - SceneTransversal& operator=(SceneTransversal const& rhs) = delete; - virtual ~SceneTransversal() noexcept = default; - - virtual SceneTask *transverse(SceneVisitor *visitor) const = 0; -}; - /** * @en Render pipeline. * @zh 渲染管线 diff --git a/native/tools/swig-config/render.i b/native/tools/swig-config/render.i index 4db861b41f0..dbaf304bec1 100644 --- a/native/tools/swig-config/render.i +++ b/native/tools/swig-config/render.i @@ -47,8 +47,6 @@ using namespace cc::render; %ignore cc::render::PipelineRuntime::isOcclusionQueryEnabled; %ignore cc::render::PipelineRuntime::resetRenderQueue; %ignore cc::render::PipelineRuntime::isRenderQueueReset; -%ignore cc::render::SceneVisitor::bindDescriptorSet; -%ignore cc::render::SceneVisitor::updateBuffer; // ----- Rename Section ------ // Brief: Classes, methods or attributes needs to be renamed @@ -118,8 +116,6 @@ using namespace cc::render; %attribute(cc::render::BasicPipeline, cc::render::PipelineType, type, getType); %attribute(cc::render::BasicPipeline, cc::render::PipelineCapabilities, capabilities, getCapabilities); %attribute(cc::render::RenderSubpassBuilder, bool, showStatistics, getShowStatistics, setShowStatistics); -%attribute(cc::render::SceneVisitor, cc::pipeline::PipelineSceneData*, pipelineSceneData, getPipelineSceneData); -%attribute(cc::render::SceneTask, cc::render::TaskType, taskType, getTaskType); // ----- Import Section ------ // Brief: Import header files which are depended by 'Include Section' From e77671bcf833bc40e3f1e8e04bbb1033da53f8e5 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Mon, 17 Jul 2023 15:01:14 +0800 Subject: [PATCH 50/57] fix lint --- cocos/gfx/base/define.ts | 8 +- cocos/gfx/base/device.ts | 15 +- cocos/gfx/webgl/webgl-commands.ts | 264 +++++++++---- cocos/gfx/webgl2/webgl2-commands.ts | 390 ++++++++++++++------ cocos/render-scene/core/pass.ts | 21 +- cocos/rendering/custom/render-graph.ts | 2 - cocos/rendering/custom/web-scene-visitor.ts | 2 +- 7 files changed, 503 insertions(+), 199 deletions(-) diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index e87a5ad54ce..53eeb4062cb 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -21,6 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* eslint-disable no-empty-function */ import { Queue } from './queue'; import { Buffer } from './buffer'; @@ -2254,8 +2255,11 @@ export function FormatSize (format: Format, width: number, height: number, depth * @param mips The target mip levels. */ export function FormatSurfaceSize ( - format: Format, width: number, height: number, - depth: number, mips: number, + format: Format, + width: number, + height: number, + depth: number, + mips: number, ): number { let size = 0; diff --git a/cocos/gfx/base/device.ts b/cocos/gfx/base/device.ts index 861c73ba74e..ff4f113b59f 100644 --- a/cocos/gfx/base/device.ts +++ b/cocos/gfx/base/device.ts @@ -388,7 +388,8 @@ export class DefaultResource { TextureType.TEX2D, TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, Format.RGBA8, - 2, 2, + 2, + 2, TextureFlagBit.NONE, )); const copyRegion = new BufferTextureCopy(0, 0, 0, new Offset(0, 0, 0), new Extent(2, 2, 1)); @@ -399,7 +400,8 @@ export class DefaultResource { TextureType.CUBE, TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, Format.RGBA8, - 2, 2, + 2, + 2, TextureFlagBit.NONE, 6, )); @@ -421,9 +423,11 @@ export class DefaultResource { TextureType.TEX3D, TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, Format.RGBA8, - 2, 2, + 2, + 2, TextureFlagBit.NONE, - 1, 1, + 1, + 1, SampleCount.X1, 2, )); @@ -435,7 +439,8 @@ export class DefaultResource { TextureType.TEX2D_ARRAY, TextureUsageBit.STORAGE | TextureUsageBit.SAMPLED, Format.RGBA8, - 2, 2, + 2, + 2, TextureFlagBit.NONE, 2, )); diff --git a/cocos/gfx/webgl/webgl-commands.ts b/cocos/gfx/webgl/webgl-commands.ts index 12dd8407db3..f64ea3cc4ea 100644 --- a/cocos/gfx/webgl/webgl-commands.ts +++ b/cocos/gfx/webgl/webgl-commands.ts @@ -348,7 +348,7 @@ function WebGLTypeToGFXType (glType: GLenum, gl: WebGLRenderingContext): Type { } } -function WebGLGetTypeSize (glType: GLenum, gl: WebGLRenderingContext): Type { +function WebGLGetTypeSize (glType: GLenum, gl: WebGLRenderingContext): number { switch (glType) { case gl.BOOL: return 4; case gl.BOOL_VEC2: return 8; @@ -375,7 +375,7 @@ function WebGLGetTypeSize (glType: GLenum, gl: WebGLRenderingContext): Type { } } -function WebGLGetComponentCount (glType: GLenum, gl: WebGLRenderingContext): Type { +function WebGLGetComponentCount (glType: GLenum, gl: WebGLRenderingContext): number { switch (glType) { case gl.FLOAT_MAT2: return 2; case gl.FLOAT_MAT3: return 3; @@ -769,8 +769,13 @@ export function WebGLCmdFuncResizeBuffer (device: WebGLDevice, gpuBuffer: IWebGL } } -export function WebGLCmdFuncUpdateBuffer (device: WebGLDevice, gpuBuffer: IWebGLGPUBuffer, buffer: Readonly, - offset: number, size: number): void { +export function WebGLCmdFuncUpdateBuffer ( + device: WebGLDevice, + gpuBuffer: IWebGLGPUBuffer, + buffer: Readonly, + offset: number, + size: number, +): void { if (gpuBuffer.usage & BufferUsageBit.UNIFORM) { if (ArrayBuffer.isView(buffer)) { gpuBuffer.vf32!.set(buffer as Float32Array, offset / Float32Array.BYTES_PER_ELEMENT); @@ -940,8 +945,17 @@ export function WebGLCmdFuncCreateTexture (device: WebGLDevice, gpuTexture: IWeb w = gpuTexture.width; h = gpuTexture.height; for (let i = 0; i < gpuTexture.mipLevel; ++i) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, i, gpuTexture.glInternalFmt, w, h, 0, - gpuTexture.glFormat, gpuTexture.glType, null); + gl.texImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + i, + gpuTexture.glInternalFmt, + w, + h, + 0, + gpuTexture.glFormat, + gpuTexture.glType, + null, + ); w = Math.max(1, w >> 1); h = Math.max(1, h >> 1); } @@ -1084,8 +1098,17 @@ export function WebGLCmdFuncResizeTexture (device: WebGLDevice, gpuTexture: IWeb w = gpuTexture.width; h = gpuTexture.height; for (let i = 0; i < gpuTexture.mipLevel; ++i) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, i, gpuTexture.glInternalFmt, w, h, - 0, gpuTexture.glFormat, gpuTexture.glType, null); + gl.texImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + i, + gpuTexture.glInternalFmt, + w, + h, + 0, + gpuTexture.glFormat, + gpuTexture.glType, + null, + ); w = Math.max(1, w >> 1); h = Math.max(1, h >> 1); } @@ -1300,7 +1323,7 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL } // parse inputs - const activeAttribCount = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_ATTRIBUTES); + const activeAttribCount: number = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_ATTRIBUTES); gpuShader.glInputs = new Array(activeAttribCount); for (let i = 0; i < activeAttribCount; ++i) { @@ -1375,9 +1398,9 @@ export function WebGLCmdFuncCreateShader (device: WebGLDevice, gpuShader: IWebGL // WebGL doesn't support Framebuffer Fetch for (let i = 0; i < gpuShader.subpassInputs.length; ++i) { const subpassInput = gpuShader.subpassInputs[i]; - gpuShader.samplerTextures.push(new UniformSamplerTexture( - subpassInput.set, subpassInput.binding, subpassInput.name, Type.SAMPLER2D, subpassInput.count, - )); + gpuShader.samplerTextures.push( + new UniformSamplerTexture(subpassInput.set, subpassInput.binding, subpassInput.name, Type.SAMPLER2D, subpassInput.count), + ); } // create uniform sampler textures @@ -2575,24 +2598,38 @@ export function WebGLCmdFuncDraw (device: WebGLDevice, drawInfo: Readonly 0) { const offset = drawInfo.firstIndex * indexBuffer.stride; - ia.drawElementsInstancedANGLE(glPrimitive, drawInfo.indexCount, - gpuInputAssembler.glIndexType, offset, drawInfo.instanceCount); + ia.drawElementsInstancedANGLE( + glPrimitive, + drawInfo.indexCount, + gpuInputAssembler.glIndexType, + offset, + drawInfo.instanceCount, + ); } } else if (drawInfo.vertexCount > 0) { ia.drawArraysInstancedANGLE(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount); @@ -2652,8 +2703,15 @@ export function WebGLCmdFuncExecuteCmds (device: WebGLDevice, cmdPackage: WebGLC switch (cmd) { case WebGLCmd.BEGIN_RENDER_PASS: { const cmd0 = cmdPackage.beginRenderPassCmds.array[cmdId]; - WebGLCmdFuncBeginRenderPass(device, cmd0.gpuRenderPass, cmd0.gpuFramebuffer, cmd0.renderArea, - cmd0.clearColors, cmd0.clearDepth, cmd0.clearStencil); + WebGLCmdFuncBeginRenderPass( + device, + cmd0.gpuRenderPass, + cmd0.gpuFramebuffer, + cmd0.renderArea, + cmd0.clearColors, + cmd0.clearDepth, + cmd0.clearStencil, + ); break; } /* @@ -2665,8 +2723,14 @@ export function WebGLCmdFuncExecuteCmds (device: WebGLDevice, cmdPackage: WebGLC */ case WebGLCmd.BIND_STATES: { const cmd2 = cmdPackage.bindStatesCmds.array[cmdId]; - WebGLCmdFuncBindStates(device, cmd2.gpuPipelineState, cmd2.gpuInputAssembler, - cmd2.gpuDescriptorSets, cmd2.dynamicOffsets, cmd2.dynamicStates); + WebGLCmdFuncBindStates( + device, + cmd2.gpuPipelineState, + cmd2.gpuInputAssembler, + cmd2.gpuDescriptorSets, + cmd2.dynamicOffsets, + cmd2.dynamicStates, + ); break; } case WebGLCmd.DRAW: { @@ -2715,9 +2779,15 @@ export function WebGLCmdFuncCopyTexImagesToTexture ( for (let i = 0; i < regions.length; i++) { const region = regions[i]; // console.debug('Copying image to texture 2D: ' + region.texExtent.width + ' x ' + region.texExtent.height); - gl.texSubImage2D(gl.TEXTURE_2D, region.texSubres.mipLevel, - region.texOffset.x, region.texOffset.y, - gpuTexture.glFormat, gpuTexture.glType, texImages[n++]); + gl.texSubImage2D( + gl.TEXTURE_2D, + region.texSubres.mipLevel, + region.texOffset.x, + region.texOffset.y, + gpuTexture.glFormat, + gpuTexture.glType, + texImages[n++], + ); } break; } @@ -2727,9 +2797,15 @@ export function WebGLCmdFuncCopyTexImagesToTexture ( // console.debug('Copying image to texture cube: ' + region.texExtent.width + ' x ' + region.texExtent.height); const fcount = region.texSubres.baseArrayLayer + region.texSubres.layerCount; for (f = region.texSubres.baseArrayLayer; f < fcount; ++f) { - gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, region.texSubres.mipLevel, - region.texOffset.x, region.texOffset.y, - gpuTexture.glFormat, gpuTexture.glType, texImages[n++]); + gl.texSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + region.texSubres.mipLevel, + region.texOffset.x, + region.texOffset.y, + gpuTexture.glFormat, + gpuTexture.glType, + texImages[n++], + ); } } break; @@ -2746,11 +2822,13 @@ export function WebGLCmdFuncCopyTexImagesToTexture ( } let stagingBuffer = new Uint8Array(1); -function pixelBufferPick (buffer: ArrayBufferView, +function pixelBufferPick ( + buffer: ArrayBufferView, format: Format, offset: number, stride: Extent, - extent: Extent): ArrayBufferView { + extent: Extent, +): ArrayBufferView { const blockHeight = formatAlignment(format).height; const bufferSize = FormatSize(format, extent.width, extent.height, extent.depth); @@ -2835,22 +2913,38 @@ export function WebGLCmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage2D(gl.TEXTURE_2D, mipLevel, - offset.x, offset.y, - destWidth, destHeight, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGLEXT.COMPRESSED_RGB_ETC1_WEBGL && !device.extensions.noCompressedTexSubImage2D) { - gl.compressedTexSubImage2D(gl.TEXTURE_2D, mipLevel, - offset.x, offset.y, - destWidth, destHeight, + gl.texSubImage2D( + gl.TEXTURE_2D, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, gpuTexture.glFormat, - pixels); + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== (WebGLEXT.COMPRESSED_RGB_ETC1_WEBGL as number) && !device.extensions.noCompressedTexSubImage2D) { + gl.compressedTexSubImage2D( + gl.TEXTURE_2D, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, + gpuTexture.glFormat, + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage2D(gl.TEXTURE_2D, mipLevel, + gl.compressedTexImage2D( + gl.TEXTURE_2D, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, 0, - pixels); + destWidth, + destHeight, + 0, + pixels, + ); } } break; @@ -2884,22 +2978,39 @@ export function WebGLCmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, - offset.x, offset.y, - destWidth, destHeight, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGLEXT.COMPRESSED_RGB_ETC1_WEBGL && !device.extensions.noCompressedTexSubImage2D) { - gl.compressedTexSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, - offset.x, offset.y, - destWidth, destHeight, + gl.texSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, + gpuTexture.glFormat, + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== (WebGLEXT.COMPRESSED_RGB_ETC1_WEBGL as number) + && !device.extensions.noCompressedTexSubImage2D) { + gl.compressedTexSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, gpuTexture.glFormat, - pixels); + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, + gl.compressedTexImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, 0, - pixels); + destWidth, + destHeight, + 0, + pixels, + ); } } } @@ -2953,8 +3064,13 @@ export function WebGLCmdFuncCopyTextureToBuffers ( gl.deleteFramebuffer(framebuffer); } -export function WebGLCmdFuncBlitTexture (device: WebGLDevice, - srcTexture: Readonly, dstTexture: IWebGLGPUTexture, regions: Readonly, filter: Filter): void { +export function WebGLCmdFuncBlitTexture ( + device: WebGLDevice, + srcTexture: Readonly, + dstTexture: IWebGLGPUTexture, + regions: Readonly, + filter: Filter, +): void { // logic different from native, because framebuffer map is not implemented in webgl device.blitManager.draw(srcTexture, dstTexture, regions as TextureBlit[], filter); } diff --git a/cocos/gfx/webgl2/webgl2-commands.ts b/cocos/gfx/webgl2/webgl2-commands.ts index ede0965f988..80f4caab35c 100644 --- a/cocos/gfx/webgl2/webgl2-commands.ts +++ b/cocos/gfx/webgl2/webgl2-commands.ts @@ -502,7 +502,7 @@ function WebGLTypeToGFXType (glType: GLenum, gl: WebGL2RenderingContext): Type { } } -function WebGLGetTypeSize (glType: GLenum, gl: WebGL2RenderingContext): Type { +function WebGLGetTypeSize (glType: GLenum, gl: WebGL2RenderingContext): number { switch (glType) { case gl.BOOL: return 4; case gl.BOOL_VEC2: return 8; @@ -967,8 +967,13 @@ export function WebGL2CmdFuncResizeBuffer (device: WebGL2Device, gpuBuffer: IWeb } } -export function WebGL2CmdFuncUpdateBuffer (device: WebGL2Device, gpuBuffer: IWebGL2GPUBuffer, buffer: Readonly, - offset: number, size: number): void { +export function WebGL2CmdFuncUpdateBuffer ( + device: WebGL2Device, + gpuBuffer: IWebGL2GPUBuffer, + buffer: Readonly, + offset: number, + size: number, +): void { if (gpuBuffer.usage & BufferUsageBit.INDIRECT) { gpuBuffer.indirects.clearDraws(); const drawInfos = (buffer as IndirectBuffer).drawInfos; @@ -1094,8 +1099,13 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW device.stateCache.glRenderbuffer = gpuTexture.glRenderbuffer; } - gl.renderbufferStorageMultisample(gl.RENDERBUFFER, gpuTexture.samples, - gpuTexture.glInternalFmt, gpuTexture.width, gpuTexture.height); + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + gpuTexture.samples, + gpuTexture.glInternalFmt, + gpuTexture.width, + gpuTexture.height, + ); } } break; @@ -1281,8 +1291,13 @@ export function WebGL2CmdFuncResizeTexture (device: WebGL2Device, gpuTexture: IW device.stateCache.glRenderbuffer = gpuTexture.glRenderbuffer; } - gl.renderbufferStorageMultisample(gl.RENDERBUFFER, gpuTexture.samples, - gpuTexture.glInternalFmt, gpuTexture.width, gpuTexture.height); + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + gpuTexture.samples, + gpuTexture.glInternalFmt, + gpuTexture.width, + gpuTexture.height, + ); } break; } @@ -1643,7 +1658,7 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb } // parse inputs - const activeAttribCount = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_ATTRIBUTES); + const activeAttribCount: number = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_ATTRIBUTES); gpuShader.glInputs = new Array(activeAttribCount); for (let i = 0; i < activeAttribCount; ++i) { @@ -1675,7 +1690,7 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb } // create uniform blocks - const activeBlockCount = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_UNIFORM_BLOCKS); + const activeBlockCount: number = gl.getProgramParameter(gpuShader.glProgram, gl.ACTIVE_UNIFORM_BLOCKS); let blockName: string; let blockIdx: number; let blockSize: number; @@ -1728,9 +1743,9 @@ export function WebGL2CmdFuncCreateShader (device: WebGL2Device, gpuShader: IWeb // WebGL doesn't support Framebuffer Fetch for (let i = 0; i < gpuShader.subpassInputs.length; ++i) { const subpassInput = gpuShader.subpassInputs[i]; - gpuShader.samplerTextures.push(new UniformSamplerTexture( - subpassInput.set, subpassInput.binding, subpassInput.name, Type.SAMPLER2D, subpassInput.count, - )); + gpuShader.samplerTextures.push( + new UniformSamplerTexture(subpassInput.set, subpassInput.binding, subpassInput.name, Type.SAMPLER2D, subpassInput.count), + ); } // create uniform sampler textures @@ -2372,8 +2387,13 @@ export function WebGL2CmdFuncBindStates ( if (cache.glBindUBOs[glBlock.glBinding] !== gpuDescriptor.gpuBuffer.glBuffer || cache.glBindUBOOffsets[glBlock.glBinding] !== offset) { if (offset) { - gl.bindBufferRange(gl.UNIFORM_BUFFER, glBlock.glBinding, gpuDescriptor.gpuBuffer.glBuffer, - offset, gpuDescriptor.gpuBuffer.size); + gl.bindBufferRange( + gl.UNIFORM_BUFFER, + glBlock.glBinding, + gpuDescriptor.gpuBuffer.glBuffer, + offset, + gpuDescriptor.gpuBuffer.size, + ); } else { gl.bindBufferBase(gl.UNIFORM_BUFFER, glBlock.glBinding, gpuDescriptor.gpuBuffer.glBuffer); } @@ -2637,24 +2657,38 @@ export function WebGL2CmdFuncDraw (device: WebGL2Device, drawInfo: Readonly 0) { const offset = drawInfo.firstIndex * indexBuffer.stride; - gl.drawElementsInstanced(glPrimitive, drawInfo.indexCount, - gpuInputAssembler.glIndexType, offset, drawInfo.instanceCount); + gl.drawElementsInstanced( + glPrimitive, + drawInfo.indexCount, + gpuInputAssembler.glIndexType, + offset, + drawInfo.instanceCount, + ); } } else if (drawInfo.vertexCount > 0) { gl.drawArraysInstanced(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount); @@ -2714,8 +2762,15 @@ export function WebGL2CmdFuncExecuteCmds (device: WebGL2Device, cmdPackage: WebG switch (cmd) { case WebGL2Cmd.BEGIN_RENDER_PASS: { const cmd0 = cmdPackage.beginRenderPassCmds.array[cmdId]; - WebGL2CmdFuncBeginRenderPass(device, cmd0.gpuRenderPass, cmd0.gpuFramebuffer, cmd0.renderArea, - cmd0.clearColors, cmd0.clearDepth, cmd0.clearStencil); + WebGL2CmdFuncBeginRenderPass( + device, + cmd0.gpuRenderPass, + cmd0.gpuFramebuffer, + cmd0.renderArea, + cmd0.clearColors, + cmd0.clearDepth, + cmd0.clearStencil, + ); break; } /* @@ -2727,8 +2782,14 @@ export function WebGL2CmdFuncExecuteCmds (device: WebGL2Device, cmdPackage: WebG */ case WebGL2Cmd.BIND_STATES: { const cmd2 = cmdPackage.bindStatesCmds.array[cmdId]; - WebGL2CmdFuncBindStates(device, cmd2.gpuPipelineState, cmd2.gpuInputAssembler, - cmd2.gpuDescriptorSets, cmd2.dynamicOffsets, cmd2.dynamicStates); + WebGL2CmdFuncBindStates( + device, + cmd2.gpuPipelineState, + cmd2.gpuInputAssembler, + cmd2.gpuDescriptorSets, + cmd2.dynamicOffsets, + cmd2.dynamicStates, + ); break; } case WebGL2Cmd.DRAW: { @@ -2789,14 +2850,29 @@ export function WebGL2CmdFuncCopyTexImagesToTexture ( switch (gpuTexture.glTarget) { case gl.TEXTURE_2D: { if (toUseTexImage2D(texImages, regions)) { - gl.texImage2D(gl.TEXTURE_2D, regions[0].texSubres.mipLevel, gpuTexture.glInternalFmt, regions[0].texExtent.width, - regions[0].texExtent.height, 0, gpuTexture.glFormat, gpuTexture.glType, texImages[0]); + gl.texImage2D( + gl.TEXTURE_2D, + regions[0].texSubres.mipLevel, + gpuTexture.glInternalFmt, + regions[0].texExtent.width, + regions[0].texExtent.height, + 0, + gpuTexture.glFormat, + gpuTexture.glType, + texImages[0], + ); } else { for (let k = 0; k < regions.length; k++) { const region = regions[k]; - gl.texSubImage2D(gl.TEXTURE_2D, region.texSubres.mipLevel, - region.texOffset.x, region.texOffset.y, - gpuTexture.glFormat, gpuTexture.glType, texImages[n++]); + gl.texSubImage2D( + gl.TEXTURE_2D, + region.texSubres.mipLevel, + region.texOffset.x, + region.texOffset.y, + gpuTexture.glFormat, + gpuTexture.glType, + texImages[n++], + ); } } break; @@ -2806,9 +2882,15 @@ export function WebGL2CmdFuncCopyTexImagesToTexture ( const region = regions[k]; const fcount = region.texSubres.baseArrayLayer + region.texSubres.layerCount; for (f = region.texSubres.baseArrayLayer; f < fcount; ++f) { - gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, region.texSubres.mipLevel, - region.texOffset.x, region.texOffset.y, - gpuTexture.glFormat, gpuTexture.glType, texImages[n++]); + gl.texSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + region.texSubres.mipLevel, + region.texOffset.x, + region.texOffset.y, + gpuTexture.glFormat, + gpuTexture.glType, + texImages[n++], + ); } } break; @@ -2824,11 +2906,13 @@ export function WebGL2CmdFuncCopyTexImagesToTexture ( } let stagingBuffer = new Uint8Array(1); -function pixelBufferPick (buffer: ArrayBufferView, +function pixelBufferPick ( + buffer: ArrayBufferView, format: Format, offset: number, stride: Extent, - extent: Extent): ArrayBufferView { + extent: Extent, +): ArrayBufferView { const blockHeight = formatAlignment(format).height; const bufferSize = FormatSize(format, extent.width, extent.height, extent.depth); @@ -2913,22 +2997,38 @@ export function WebGL2CmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage2D(gl.TEXTURE_2D, mipLevel, - offset.x, offset.y, - destWidth, destHeight, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL) { - gl.compressedTexSubImage2D(gl.TEXTURE_2D, mipLevel, - offset.x, offset.y, - destWidth, destHeight, + gl.texSubImage2D( + gl.TEXTURE_2D, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, + gpuTexture.glFormat, + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL as number) { + gl.compressedTexSubImage2D( + gl.TEXTURE_2D, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, gpuTexture.glFormat, - pixels); + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage2D(gl.TEXTURE_2D, mipLevel, + gl.compressedTexImage2D( + gl.TEXTURE_2D, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, 0, - pixels); + destWidth, + destHeight, + 0, + pixels, + ); } } break; @@ -2965,22 +3065,43 @@ export function WebGL2CmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, - offset.x, offset.y, offset.z, - destWidth, destHeight, extent.depth, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL) { - gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, - offset.x, offset.y, offset.z, - destWidth, destHeight, extent.depth, + gl.texSubImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, + offset.x, + offset.y, + offset.z, + destWidth, + destHeight, + extent.depth, gpuTexture.glFormat, - pixels); + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL as number) { + gl.compressedTexSubImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, + offset.x, + offset.y, + offset.z, + destWidth, + destHeight, + extent.depth, + gpuTexture.glFormat, + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, + gl.compressedTexImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, extent.depth, 0, - pixels); + destWidth, + destHeight, + extent.depth, + 0, + pixels, + ); } } } @@ -3015,22 +3136,43 @@ export function WebGL2CmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, - offset.x, offset.y, offset.z, - destWidth, destHeight, extent.depth, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL) { - gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, - offset.x, offset.y, offset.z, - destWidth, destHeight, extent.depth, + gl.texSubImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, + offset.x, + offset.y, + offset.z, + destWidth, + destHeight, + extent.depth, gpuTexture.glFormat, - pixels); + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL as number) { + gl.compressedTexSubImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, + offset.x, + offset.y, + offset.z, + destWidth, + destHeight, + extent.depth, + gpuTexture.glFormat, + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, mipLevel, + gl.compressedTexImage3D( + gl.TEXTURE_2D_ARRAY, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, extent.depth, 0, - pixels); + destWidth, + destHeight, + extent.depth, + 0, + pixels, + ); } } break; @@ -3064,22 +3206,38 @@ export function WebGL2CmdFuncCopyBuffersToTexture ( } if (!isCompressed) { - gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, - offset.x, offset.y, - destWidth, destHeight, - gpuTexture.glFormat, gpuTexture.glType, - pixels); - } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL) { - gl.compressedTexSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, - offset.x, offset.y, - destWidth, destHeight, + gl.texSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, gpuTexture.glFormat, - pixels); + gpuTexture.glType, + pixels, + ); + } else if (gpuTexture.glInternalFmt !== WebGL2EXT.COMPRESSED_RGB_ETC1_WEBGL as number) { + gl.compressedTexSubImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, + offset.x, + offset.y, + destWidth, + destHeight, + gpuTexture.glFormat, + pixels, + ); } else { // WEBGL_compressed_texture_etc1 - gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, mipLevel, + gl.compressedTexImage2D( + gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, + mipLevel, gpuTexture.glInternalFmt, - destWidth, destHeight, 0, - pixels); + destWidth, + destHeight, + 0, + pixels, + ); } } } @@ -3168,9 +3326,16 @@ export function WebGL2CmdFuncBlitFramebuffer ( const glFilter = (filter === Filter.LINEAR || filter === Filter.ANISOTROPIC) ? gl.LINEAR : gl.NEAREST; gl.blitFramebuffer( - srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, - dstRect.x, dstRect.y, dstRect.x + dstRect.width, dstRect.y + dstRect.height, - mask, glFilter, + srcRect.x, + srcRect.y, + srcRect.x + srcRect.width, + srcRect.y + srcRect.height, + dstRect.x, + dstRect.y, + dstRect.x + dstRect.width, + dstRect.y + dstRect.height, + mask, + glFilter, ); if (rebindFBO) { @@ -3205,7 +3370,7 @@ export function WebGL2CmdFuncBlitTexture ( const blitInfo = (formatInfo: FormatInfo): { mask: number; attachment: number; } => { let mask = 0; - let attachment = gl.COLOR_ATTACHMENT0; + let attachment: number = gl.COLOR_ATTACHMENT0; if (formatInfo.hasStencil) { attachment = gl.DEPTH_STENCIL_ATTACHMENT; @@ -3269,9 +3434,16 @@ export function WebGL2CmdFuncBlitTexture ( } gl.blitFramebuffer( - region.srcOffset.x, region.srcOffset.y, region.srcOffset.x + region.srcExtent.width, region.srcOffset.y + region.srcExtent.height, - region.dstOffset.x, region.dstOffset.y, region.dstOffset.x + region.dstExtent.width, region.dstOffset.y + region.dstExtent.height, - srcMask, glFilter, + region.srcOffset.x, + region.srcOffset.y, + region.srcOffset.x + region.srcExtent.width, + region.srcOffset.y + region.srcExtent.height, + region.dstOffset.x, + region.dstOffset.y, + region.dstOffset.x + region.dstExtent.width, + region.dstOffset.y + region.dstExtent.height, + srcMask, + glFilter, ); } diff --git a/cocos/render-scene/core/pass.ts b/cocos/render-scene/core/pass.ts index 1e728580193..4345d8c5003 100644 --- a/cocos/render-scene/core/pass.ts +++ b/cocos/render-scene/core/pass.ts @@ -184,7 +184,7 @@ export class Pass { protected _shaderInfo: IProgramInfo = null!; protected _defines: MacroRecord = {}; protected _properties: Record = {}; - protected _shader: Shader | null = null + protected _shader: Shader | null = null; protected _bs: BlendState = new BlendState(); protected _dss: DepthStencilState = new DepthStencilState(); protected _rs: RasterizerState = new RasterizerState(); @@ -491,7 +491,10 @@ export class Pass { if (cclegacy.rendering && cclegacy.rendering.enableEffectImport) { const programLib = cclegacy.rendering.programLib as ProgramLibrary; const program = programLib.getProgramVariant( - this._device, this._phaseID, this._programName, this._defines, + this._device, + this._phaseID, + this._programName, + this._defines, ); if (!program) { warnID(12103, this._programName); @@ -692,8 +695,11 @@ export class Pass { const bufferView = this._buffers[binding] = device.createBuffer(_bufferViewInfo); // non-builtin UBO data pools, note that the effect compiler // guarantees these bindings to be consecutive, starting from 0 and non-array-typed - this._blocks[binding] = new Float32Array(this._rootBlock!, _bufferViewInfo.offset, - size / Float32Array.BYTES_PER_ELEMENT); + this._blocks[binding] = new Float32Array( + this._rootBlock!, + _bufferViewInfo.offset, + size / Float32Array.BYTES_PER_ELEMENT, + ); this._blocksInt[binding] = new Int32Array(this._blocks[binding].buffer, this._blocks[binding].byteOffset, this._blocks[binding].length); this._descriptorSet.bindBuffer(binding, bufferView); } @@ -737,8 +743,11 @@ export class Pass { const bufferView = this._buffers[binding] = device.createBuffer(_bufferViewInfo); // non-builtin UBO data pools, note that the effect compiler // guarantees these bindings to be consecutive, starting from 0 and non-array-typed - this._blocks[binding] = new Float32Array(this._rootBlock!, _bufferViewInfo.offset, - size / Float32Array.BYTES_PER_ELEMENT); + this._blocks[binding] = new Float32Array( + this._rootBlock!, + _bufferViewInfo.offset, + size / Float32Array.BYTES_PER_ELEMENT, + ); this._blocksInt[binding] = new Int32Array(this._blocks[binding].buffer, this._blocks[binding].byteOffset, this._blocks[binding].length); this._descriptorSet.bindBuffer(binding, bufferView); } diff --git a/cocos/rendering/custom/render-graph.ts b/cocos/rendering/custom/render-graph.ts index 83c64213c5b..41078871395 100644 --- a/cocos/rendering/custom/render-graph.ts +++ b/cocos/rendering/custom/render-graph.ts @@ -172,8 +172,6 @@ export class Subpass { //================================================================= // Graph Concept export class SubpassGraphVertex { - constructor () { - } readonly _outEdges: OutE[] = []; readonly _inEdges: OutE[] = []; } diff --git a/cocos/rendering/custom/web-scene-visitor.ts b/cocos/rendering/custom/web-scene-visitor.ts index a50cdb851e3..04f4e94bb19 100644 --- a/cocos/rendering/custom/web-scene-visitor.ts +++ b/cocos/rendering/custom/web-scene-visitor.ts @@ -51,7 +51,7 @@ export class WebSceneVisitor implements SceneVisitor { public bindInputAssembler (ia: InputAssembler): void { this._commandBuffer.bindInputAssembler(ia); } - public draw (info: DrawInfo): void { + public draw (info: DrawInfo | InputAssembler): void { this._commandBuffer.draw(info); } public updateBuffer (buffer: Buffer, data: ArrayBuffer, size?: number): void { From c7438ae8935bd583fef3947ab73a31e6c0a74403 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Mon, 17 Jul 2023 16:03:04 +0800 Subject: [PATCH 51/57] fix lint --- cocos/rendering/custom/index.jsb.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/rendering/custom/index.jsb.ts b/cocos/rendering/custom/index.jsb.ts index e0631e8ea1e..7aa8b0d0a23 100644 --- a/cocos/rendering/custom/index.jsb.ts +++ b/cocos/rendering/custom/index.jsb.ts @@ -25,7 +25,7 @@ declare const render: any; import { Pipeline, PipelineBuilder, RenderingModule } from './pipeline'; -import { DeferredPipelineBuilder, ForwardPipelineBuilder } from './builtin-pipelines'; +import { DeferredPipelineBuilder } from './builtin-pipelines'; import { CustomPipelineBuilder, TestPipelineBuilder } from './custom-pipeline'; import { Device } from '../../gfx'; import { PostProcessBuilder } from '../post-process/post-process-builder'; From 0a5d7b9db5b6e819913d76cdf9485fb91dd16a46 Mon Sep 17 00:00:00 2001 From: GengineJS <476393671@qq.com> Date: Mon, 17 Jul 2023 19:02:13 +0800 Subject: [PATCH 52/57] [Fixed] eslint (#152) --- .../reflection-probe-component.ts | 8 +- cocos/rendering/custom/executor.ts | 169 ++++++--- cocos/rendering/custom/web-pipeline.ts | 341 +++++++++++------- 3 files changed, 337 insertions(+), 181 deletions(-) diff --git a/cocos/3d/reflection-probe/reflection-probe-component.ts b/cocos/3d/reflection-probe/reflection-probe-component.ts index ec66ef564b2..9c94934eef3 100644 --- a/cocos/3d/reflection-probe/reflection-probe-component.ts +++ b/cocos/3d/reflection-probe/reflection-probe-component.ts @@ -23,7 +23,7 @@ */ import { ccclass, executeInEditMode, menu, playOnFocus, serializable, tooltip, type, visible } from 'cc.decorator'; import { EDITOR, EDITOR_NOT_IN_PREVIEW } from 'internal:constants'; -import { CCBoolean, CCObject, Color, Enum, Vec3 } from '../../core'; +import { CCBoolean, CCObject, Color, Enum, Vec3, warn } from '../../core'; import { TextureCube } from '../../asset/assets'; import { scene } from '../../render-scene'; @@ -127,7 +127,7 @@ export class ReflectionProbe extends Component { * @zh 设置探针类型,环境反射或者平面反射 */ @type(Enum(ProbeType)) - set probeType (value: number) { + set probeType (value: ProbeType) { this.probe.probeType = value; if (value !== this._probeType) { const lastSize = this._size.clone(); @@ -151,7 +151,7 @@ export class ReflectionProbe extends Component { this._objFlags ^= CCObject.Flags.IsRotationLocked; } if (!this._sourceCamera) { - console.warn('the reflection camera is invalid, please set the reflection camera'); + warn('the reflection camera is invalid, please set the reflection camera'); } else { this.probe.switchProbeType(value, this._sourceCamera.camera); } @@ -163,7 +163,7 @@ export class ReflectionProbe extends Component { this.size = this._size; } } - get probeType (): number { + get probeType (): ProbeType { return this._probeType; } diff --git a/cocos/rendering/custom/executor.ts b/cocos/rendering/custom/executor.ts index b699cd72035..b5492e7a13c 100644 --- a/cocos/rendering/custom/executor.ts +++ b/cocos/rendering/custom/executor.ts @@ -51,6 +51,7 @@ import { Framebuffer, FramebufferInfo, GeneralBarrierInfo, + InputAssembler, InputAssemblerInfo, LoadOp, MemoryUsageBit, @@ -58,6 +59,7 @@ import { Rect, RenderPass, RenderPassInfo, + Shader, StoreOp, SurfaceTransform, Swapchain, @@ -482,7 +484,7 @@ class DeviceRenderQueue { get renderPhase (): RenderPhaseData | null { return this._renderPhase; } get viewport (): Viewport | null { return this._viewport; } get scissor (): Rect | null { return this._scissor; } - private _sceneVisitor; + private _sceneVisitor!: WebSceneVisitor; private _blitDesc: BlitDesc | null = null; private _queueId = -1; set queueId (val) { this._queueId = val; } @@ -505,8 +507,10 @@ class DeviceRenderQueue { this._devicePass = devicePass; if (isEnableEffect()) this._phaseID = cclegacy.rendering.getPhaseID(devicePass.passID, context.renderGraph.getLayout(id) || 'default'); if (!this._sceneVisitor) { - this._sceneVisitor = new WebSceneVisitor(context.commandBuffer, - context.pipeline.pipelineSceneData); + this._sceneVisitor = new WebSceneVisitor( + context.commandBuffer, + context.pipeline.pipelineSceneData, + ); } } createBlitDesc (blit: Blit): void { @@ -612,7 +616,7 @@ class RenderPassLayoutInfo { protected _layout: PipelineLayoutData; protected _inputName: string; protected _descriptorSet: DescriptorSet | null = null; - constructor (layoutId, input: [string, ComputeView[]]) { + constructor (layoutId: number, input: [string, ComputeView[]]) { this._inputName = input[0]; this._layoutID = layoutId; const lg = context.layoutGraph; @@ -831,9 +835,11 @@ class DeviceRenderPass { // )); // } this._renderPass = device.createRenderPass(new RenderPassInfo(colors, depthStencilAttachment)); - this._framebuffer = framebuffer || device.createFramebuffer(new FramebufferInfo(this._renderPass, + this._framebuffer = framebuffer || device.createFramebuffer(new FramebufferInfo( + this._renderPass, swapchain ? [swapchain.colorTexture] : colorTexs, - swapchain ? swapchain.depthStencilTexture : depthTex)); + swapchain ? swapchain.depthStencilTexture : depthTex, + )); } get layoutName (): string { return this._layoutName; } get passID (): number { return this._passID; } @@ -898,8 +904,13 @@ class DeviceRenderPass { const pass = submodel.passes[0]; const ia = submodel.inputAssembler; const device = context.device; - const pso = PipelineStateManager.getOrCreatePipelineState(device, pass, - submodel.shaders[0], renderPass, ia); + const pso = PipelineStateManager.getOrCreatePipelineState( + device, + pass, + submodel.shaders[0], + renderPass, + ia, + ); const descData = getDescriptorSetDataFromLayoutId(pass.passID)!; mergeSrcToTargetDesc(descData.descriptorSet, context.pipeline.descriptorSet, true); profilerViewport.width = rect.width; @@ -928,10 +939,18 @@ class DeviceRenderPass { renderPassArea.width = tex.width; renderPassArea.height = tex.height; } - cmdBuff.beginRenderPass(this.renderPass, this.framebuffer, renderPassArea, - this.clearColor, this.clearDepth, this.clearStencil); - cmdBuff.bindDescriptorSet(SetIndex.GLOBAL, - context.pipeline.descriptorSet); + cmdBuff.beginRenderPass( + this.renderPass, + this.framebuffer, + renderPassArea, + this.clearColor, + this.clearDepth, + this.clearStencil, + ); + cmdBuff.bindDescriptorSet( + SetIndex.GLOBAL, + context.pipeline.descriptorSet, + ); for (const queue of this._deviceQueues) { queue.record(); } @@ -1091,7 +1110,7 @@ class GraphScene { } this.blit = null; } - init (scene, blit, sceneID): void { + init (scene: SceneData | null, blit: Blit | null, sceneID): void { this._copyScene(scene); this._copyBlit(blit); this.sceneID = sceneID; @@ -1104,8 +1123,12 @@ class DevicePreSceneTask extends WebSceneTask { protected _graphScene: GraphScene; private _cmdBuff: CommandBuffer; constructor (queue: DeviceRenderQueue, graphScene: GraphScene, visitor: SceneVisitor) { - super(context.pipelineSceneData, context.ubo, - graphScene.scene && graphScene.scene.camera ? graphScene.scene.camera : null, visitor); + super( + context.pipelineSceneData, + context.ubo, + graphScene.scene && graphScene.scene.camera ? graphScene.scene.camera : null, + visitor, + ); this._currentQueue = queue; this._graphScene = graphScene; this._renderPass = queue.devicePass.renderPass; @@ -1173,6 +1196,7 @@ class DevicePreSceneTask extends WebSceneTask { const probes = cclegacy.internal.reflectionProbeManager.getProbes(); for (let i = 0; i < probes.length; i++) { if (probes[i].hasFrameBuffer(this._currentQueue.devicePass.framebuffer)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument this._submitInfo.reflectionProbe.gatherRenderObjects(probes[i], this.camera, this._cmdBuff); break; } @@ -1239,7 +1263,7 @@ class DevicePreSceneTask extends WebSceneTask { protected _insertRenderList (ro: RenderObject, subModelIdx: number, passIdx: number, isTransparent = false): void { const subModel = ro.model.subModels[subModelIdx]; - const pass = subModel.passes[passIdx]; + const pass: Pass = subModel.passes[passIdx]; const shader = subModel.shaders[passIdx]; const currTransparent = pass.blendState.targets[0].blend; const devicePass = this._currentQueue.devicePass; @@ -1249,7 +1273,7 @@ class DevicePreSceneTask extends WebSceneTask { if (currTransparent !== isTransparent || !(pass.phaseID & (isTransparent ? phase : this._currentQueue.phaseID))) { return; } - const hash = (0 << 30) | pass.priority << 16 | subModel.priority << 8 | passIdx; + const hash = (0 << 30) | pass.priority as number << 16 | subModel.priority as number << 8 | passIdx; const rp = context.pools.addPassInfo(); rp.priority = ro.model.priority; rp.hash = hash; @@ -1310,8 +1334,12 @@ class DeviceSceneTask extends WebSceneTask { protected _renderPass: RenderPass; protected _graphScene: GraphScene; constructor (queue: DeviceRenderQueue, graphScene: GraphScene, visitor: SceneVisitor) { - super(context.pipelineSceneData, context.ubo, - graphScene.scene && graphScene.scene.camera ? graphScene.scene.camera : null, visitor); + super( + context.pipelineSceneData, + context.ubo, + graphScene.scene && graphScene.scene.camera ? graphScene.scene.camera : null, + visitor, + ); this._currentQueue = queue; this._renderPass = this._currentQueue.devicePass.renderPass; this._graphScene = graphScene; @@ -1335,14 +1363,20 @@ class DeviceSceneTask extends WebSceneTask { : currSubmitInfo.opaqueList; for (let i = 0; i < renderList.length; ++i) { const { subModel, passIdx } = renderList[i]; - const { inputAssembler } = subModel; - const pass = subModel.passes[passIdx]; - const shader = subModel.shaders[passIdx]; - const pso = PipelineStateManager.getOrCreatePipelineState(deviceManager.gfxDevice, - pass, shader, this._renderPass, inputAssembler); + const inputAssembler: InputAssembler = subModel.inputAssembler; + const pass: Pass = subModel.passes[passIdx]; + const shader: Shader = subModel.shaders[passIdx]; + const descriptorSet: DescriptorSet = subModel.descriptorSet; + const pso = PipelineStateManager.getOrCreatePipelineState( + deviceManager.gfxDevice, + pass, + shader, + this._renderPass, + inputAssembler, + ); this.visitor.bindPipelineState(pso); this.visitor.bindDescriptorSet(SetIndex.MATERIAL, pass.descriptorSet); - this.visitor.bindDescriptorSet(SetIndex.LOCAL, subModel.descriptorSet); + this.visitor.bindDescriptorSet(SetIndex.LOCAL, descriptorSet); this.visitor.bindInputAssembler(inputAssembler); this.visitor.draw(inputAssembler); } @@ -1366,13 +1400,18 @@ class DeviceSceneTask extends WebSceneTask { const instance = instances[b]; if (!instance.count) { continue; } const shader = instance.shader!; - const pso = PipelineStateManager.getOrCreatePipelineState(deviceManager.gfxDevice, pass, - shader, this._renderPass, instance.ia); + const pso = PipelineStateManager.getOrCreatePipelineState( + deviceManager.gfxDevice, + pass, + shader, + this._renderPass, + instance.ia, + ); if (lastPSO !== pso) { this.visitor.bindPipelineState(pso); lastPSO = pso; } - const ia: any = instance.ia; + const ia: InputAssembler = instance.ia; this.visitor.bindDescriptorSet(SetIndex.LOCAL, instance.descriptorSet, res.value.dynamicOffsets); this.visitor.bindInputAssembler(ia); this.visitor.draw(ia); @@ -1397,7 +1436,7 @@ class DeviceSceneTask extends WebSceneTask { const pass = batch.passes[j]; if (((isEnableEffect()) ? pass.phaseID : pass.phase) !== this._currentQueue.phaseID) continue; const shader = batch.shaders[j]; - const inputAssembler: any = batch.inputAssembler!; + const inputAssembler: InputAssembler = batch.inputAssembler!; const pso = PipelineStateManager.getOrCreatePipelineState(deviceManager.gfxDevice, pass, shader, this._renderPass, inputAssembler); this.visitor.bindPipelineState(pso); this.visitor.bindDescriptorSet(SetIndex.MATERIAL, pass.descriptorSet); @@ -1414,14 +1453,22 @@ class DeviceSceneTask extends WebSceneTask { protected _recordShadowMap (): void { const submitMap = context.submitMap; const currSubmitInfo = submitMap.get(this.camera!)!.get(this._currentQueue.phaseID)!; - currSubmitInfo.shadowMap.get(this.graphScene.sceneID)!.recordCommandBuffer(context.device, - this._renderPass, context.commandBuffer); + currSubmitInfo.shadowMap.get(this.graphScene.sceneID)!.recordCommandBuffer( + context.device, + this._renderPass, + + context.commandBuffer, + ); } protected _recordReflectionProbe (): void { const submitMap = context.submitMap; const currSubmitInfo = submitMap.get(this.camera!)!.get(this._currentQueue.phaseID)!; - currSubmitInfo.reflectionProbe?.recordCommandBuffer(context.device, - this._renderPass, context.commandBuffer); + currSubmitInfo.reflectionProbe?.recordCommandBuffer( + context.device, + this._renderPass, + + context.commandBuffer, + ); } private _clearExtBlitDesc (desc, extResId: number[]): void { @@ -1448,12 +1495,17 @@ class DeviceSceneTask extends WebSceneTask { pass.update(); const shader = pass.getShaderVariant(); const devicePass = this._currentQueue.devicePass; - const screenIa: any = this._currentQueue.blitDesc!.screenQuad!.quadIA; + const screenIa: InputAssembler = this._currentQueue.blitDesc!.screenQuad!.quadIA!; const globalDesc = context.pipeline.descriptorSet; - let pso; + let pso: PipelineState | null = null; if (pass !== null && shader !== null && screenIa !== null) { - pso = PipelineStateManager.getOrCreatePipelineState(context.device, pass, shader, - devicePass.renderPass, screenIa); + pso = PipelineStateManager.getOrCreatePipelineState( + context.device, + pass, + shader, + devicePass.renderPass, + screenIa, + ); } if (pso) { this.visitor.bindPipelineState(pso); @@ -1474,18 +1526,22 @@ class DeviceSceneTask extends WebSceneTask { const devicePass = this._currentQueue.devicePass; const submitMap = context.submitMap; const currSubmitInfo = submitMap.get(this.camera!)!.get(this._currentQueue.phaseID)!; - currSubmitInfo.additiveLight?.recordCommandBuffer(context.device, + currSubmitInfo.additiveLight?.recordCommandBuffer( + context.device, this._renderPass, - context.commandBuffer); + context.commandBuffer, + ); } private _recordPlanarShadows (): void { const devicePass = this._currentQueue.devicePass; const submitMap = context.submitMap; const currSubmitInfo = submitMap.get(this.camera!)!.get(this._currentQueue.phaseID)!; - currSubmitInfo.planarQueue?.recordCommandBuffer(context.device, + currSubmitInfo.planarQueue?.recordCommandBuffer( + context.device, this._renderPass, - context.commandBuffer); + context.commandBuffer, + ); } protected _updateGlobal (data: RenderData): void { const devicePass = this._currentQueue.devicePass; @@ -1572,8 +1628,10 @@ class DeviceSceneTask extends WebSceneTask { if (graphSceneData.flags & SceneFlags.DEFAULT_LIGHTING) { this._recordAdditiveLights(); } - this.visitor.bindDescriptorSet(SetIndex.GLOBAL, - context.pipeline.descriptorSet); + this.visitor.bindDescriptorSet( + SetIndex.GLOBAL, + context.pipeline.descriptorSet, + ); if (graphSceneData.flags & SceneFlags.PLANAR_SHADOW) { this._recordPlanarShadows(); } @@ -1581,8 +1639,12 @@ class DeviceSceneTask extends WebSceneTask { this._recordTransparentList(); } if (graphSceneData.flags & SceneFlags.GEOMETRY) { - this.camera!.geometryRenderer?.render(devicePass.renderPass, - context.commandBuffer, context.pipeline.pipelineSceneData); + this.camera!.geometryRenderer?.render( + devicePass.renderPass, + context.commandBuffer, + + context.pipeline.pipelineSceneData, + ); } if (graphSceneData.flags & SceneFlags.UI) { this._recordUI(); @@ -1769,7 +1831,7 @@ class BlitInfo { const vbStride = Float32Array.BYTES_PER_ELEMENT * 4; const vbSize = vbStride * 4; const device = cclegacy.director.root.device; - const quadVB = device.createBuffer(new BufferInfo( + const quadVB: Buffer = device.createBuffer(new BufferInfo( BufferUsageBit.VERTEX | BufferUsageBit.TRANSFER_DST, MemoryUsageBit.DEVICE | MemoryUsageBit.HOST, vbSize, @@ -1784,7 +1846,7 @@ class BlitInfo { const ibStride = Uint8Array.BYTES_PER_ELEMENT; const ibSize = ibStride * 6; - const quadIB = device.createBuffer(new BufferInfo( + const quadIB: Buffer = device.createBuffer(new BufferInfo( BufferUsageBit.INDEX | BufferUsageBit.TRANSFER_DST, MemoryUsageBit.DEVICE, ibSize, @@ -1821,14 +1883,16 @@ class BlitInfo { } class ExecutorContext { - constructor (pipeline: BasicPipeline, + constructor ( + pipeline: BasicPipeline, ubo: PipelineUBO, device: Device, resourceGraph: ResourceGraph, renderGraph: RenderGraph, layoutGraph: LayoutGraphData, width: number, - height: number) { + height: number, + ) { this.pipeline = pipeline; this.device = device; this.commandBuffer = device.commandBuffer; @@ -1881,12 +1945,15 @@ class ExecutorContext { } export class Executor { - constructor (pipeline: BasicPipeline, + constructor ( + pipeline: BasicPipeline, ubo: PipelineUBO, device: Device, resourceGraph: ResourceGraph, layoutGraph: LayoutGraphData, - width: number, height: number) { + width: number, + height: number, + ) { context = this._context = new ExecutorContext( pipeline, ubo, diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index c85a9cdbeef..1b30db086fb 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -25,8 +25,8 @@ /* eslint-disable max-len */ import { systemInfo } from 'pal/system-info'; import { DEBUG } from 'internal:constants'; -import { Color, Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, UniformBlock, ResolveMode, SampleCount } from '../../gfx'; -import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy } from '../../core'; +import { Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, UniformBlock, ResolveMode, SampleCount, Color } from '../../gfx'; +import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy, IVec4Like, IMat4Like, IVec2Like } from '../../core'; import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities, BasicMultisampleRenderPassBuilder } from './pipeline'; @@ -54,6 +54,9 @@ import { getUBOTypeCount } from './utils'; import { initGlobalDescBinding } from './define'; import { createGfxDescriptorSetsAndPipelines } from './layout-graph-utils'; import { Root } from '../../root'; +import { CSMLayers, CSMShadowLayer } from '../shadow/csm-layers'; +import { Scene } from '../../scene-graph'; +import { Director } from '../../game'; const _uboVec = new Vec4(); const _uboVec3 = new Vec3(); @@ -75,32 +78,34 @@ export class WebSetter { this._lg = lg; } - protected _copyToBuffer (target: any, offset: number, type: Type): void { + protected _copyToBuffer (target: IVec4Like | Quat | IVec2Like | IMat4Like | number, offset: number, type: Type): void { assert(offset !== -1); const arr = this.getCurrConstant(); switch (type) { case Type.FLOAT4: - Vec4.toArray(arr, target, offset); + Vec4.toArray(arr, target as IVec4Like, offset); break; case Type.MAT4: - Mat4.toArray(arr, target, offset); + Mat4.toArray(arr, target as IMat4Like, offset); break; case Type.FLOAT: - arr[offset] = target; + arr[offset] = target as number; break; case Type.SAMPLER2D: break; case Type.TEXTURE2D: break; - case Type.FLOAT2: - arr[offset + 0] = target.x; - arr[offset + 1] = target.y; + case Type.FLOAT2: { + const vec2Val = target as IVec2Like; + arr[offset + 0] = vec2Val.x; + arr[offset + 1] = vec2Val.y; + } break; default: } } - protected _applyCurrConstantBuffer (name: string, target: any, type: Type, idx = 0): void { + protected _applyCurrConstantBuffer (name: string, target: IVec4Like | Quat | IVec2Like | IMat4Like | number, type: Type, idx = 0): void { const offset = this.getUniformOffset(name, type, idx); this._copyToBuffer(target, offset, type); } @@ -189,7 +194,7 @@ export class WebSetter { this._currCount += getUBOTypeCount(uniform.type) * uniform.count; } if (!this._data.constants.get(num)) { - const value = new Array(this._currCount); + const value: number[] = new Array(this._currCount); value.fill(0); this._data.constants.set(num, value); } @@ -283,16 +288,18 @@ export class WebSetter { protected _data: RenderData; protected _lg: LayoutGraphData; protected _currBlock; - protected _currStage; + protected _currStage: string = ''; protected _currCount; protected _currConstant: number[] = []; } -function setShadowUBOLightView (setter: WebSetter, +function setShadowUBOLightView ( + setter: WebSetter, camera: Camera, light: Light, level: number, - layout = 'default'): void { + layout = 'default', +): void { const director = cclegacy.director; const pipeline = (director.root as Root).pipeline; const device = pipeline.device; @@ -319,9 +326,9 @@ function setShadowUBOLightView (setter: WebSetter, if (shadowInfo.type === ShadowType.ShadowMap) { let near = 0.1; let far = 0; - let matShadowView; - let matShadowProj; - let matShadowViewProj; + let matShadowView: Mat4; + let matShadowProj: Mat4; + let matShadowViewProj: Mat4; let levelCount = 0; if (mainLight.shadowFixedArea || mainLight.csmLevel === CSMLevel.LEVEL_1) { matShadowView = csmLayers.specialLayer.matShadowView; @@ -394,12 +401,21 @@ function setShadowUBOLightView (setter: WebSetter, const matViewOffset = setter.getUniformOffset('cc_matLightView', Type.MAT4); const matViewProOffset = setter.getUniformOffset('cc_matLightViewProj', Type.MAT4); if (setter.hasUniform(matViewOffset) || setter.hasUniform(matViewProOffset)) { - Mat4.invert(_matView, (light as any).node.getWorldMatrix()); + Mat4.invert(_matView, spotLight.node!.getWorldMatrix()); } if (setter.hasUniform(matViewOffset)) setter.offsetMat4(_matView, matViewOffset); if (setter.hasUniform(matViewProOffset)) { - Mat4.perspective(_mulMatView, (light as any).angle, 1.0, 0.001, (light as any).range, - true, cap.clipSpaceMinZ, cap.clipSpaceSignY, 0); + Mat4.perspective( + _mulMatView, + spotLight.angle, + 1.0, + 0.001, + spotLight.range, + true, + cap.clipSpaceMinZ, + cap.clipSpaceSignY, + 0, + ); Mat4.multiply(_matView, _mulMatView, _matView); setter.offsetMat4(_matView, matViewProOffset); } @@ -449,12 +465,12 @@ function getPCFRadius (shadowInfo: Shadows, mainLight: DirectionalLight): number function setShadowUBOView (setter: WebSetter, camera: Camera | null, layout = 'default'): void { const director = cclegacy.director; const pipeline = director.root.pipeline; - const device = pipeline.device; + const device: Device = pipeline.device; const scene = director.getScene(); - const mainLight = camera && camera.scene ? camera.scene.mainLight : scene ? scene.renderScene.mainLight : null; + const mainLight: DirectionalLight = camera && camera.scene ? camera.scene.mainLight : scene ? scene.renderScene.mainLight : null; const sceneData = pipeline.pipelineSceneData; - const shadowInfo = sceneData.shadows; - const csmLayers = sceneData.csmLayers; + const shadowInfo: Shadows = sceneData.shadows; + const csmLayers: CSMLayers = sceneData.csmLayers; const csmSupported = sceneData.csmSupported; const packing = supportsR32FloatTexture(device) ? 0.0 : 1.0; const hasCCShadow = setter.addConstant('CCShadow', layout); @@ -465,11 +481,11 @@ function setShadowUBOView (setter: WebSetter, camera: Camera | null, layout = 'd if (mainLight.shadowFixedArea || mainLight.csmLevel === CSMLevel.LEVEL_1 || !csmSupported) { if (hasCCShadow) { setter.setCurrConstant('CCShadow', layout); - const matShadowView = csmLayers.specialLayer.matShadowView; - const matShadowProj = csmLayers.specialLayer.matShadowProj; - const matShadowViewProj = csmLayers.specialLayer.matShadowViewProj; - const near = mainLight.shadowNear; - const far = mainLight.shadowFar; + const matShadowView: Mat4 = csmLayers.specialLayer.matShadowView; + const matShadowProj: Mat4 = csmLayers.specialLayer.matShadowProj; + const matShadowViewProj: Mat4 = csmLayers.specialLayer.matShadowViewProj; + const near: number = mainLight.shadowNear; + const far: number = mainLight.shadowFar; uniformOffset = setter.getUniformOffset('cc_matLightView', Type.MAT4); if (setter.hasUniform(uniformOffset)) { setter.offsetMat4(matShadowView, uniformOffset); @@ -504,8 +520,8 @@ function setShadowUBOView (setter: WebSetter, camera: Camera | null, layout = 'd const layerThreshold = getPCFRadius(shadowInfo, mainLight); setter.setCurrConstant('CCCSM', layout); for (let i = 0; i < mainLight.csmLevel; i++) { - const layer = csmLayers.layers[i]; - const matShadowView = layer.matShadowView; + const layer: CSMShadowLayer = csmLayers.layers[i]; + const matShadowView: Mat4 = layer.matShadowView; uniformOffset = setter.getUniformOffset('cc_csmViewDir0', Type.FLOAT4, i); if (setter.hasUniform(uniformOffset)) { _uboVec.set(matShadowView.m00, matShadowView.m04, matShadowView.m08, layerThreshold); @@ -591,10 +607,13 @@ function setShadowUBOView (setter: WebSetter, camera: Camera | null, layout = 'd } } -function setCameraUBOValues (setter: WebSetter, - camera: Readonly | null, cfg: Readonly, - scene: Readonly, - layoutName = 'default'): void { +function setCameraUBOValues ( + setter: WebSetter, + camera: Readonly | null, + cfg: Readonly, + scene: RenderScene | null, + layoutName = 'default', +): void { const director = cclegacy.director; const root = director.root; const pipeline = root.pipeline as WebPipeline; @@ -741,14 +760,14 @@ function setTextureUBOView (setter: WebSetter, camera: Camera | null, cfg: Reado const root = director.root; if (skybox.reflectionMap) { const texture = skybox.reflectionMap.getGFXTexture()!; - const sampler = root.device.getSampler(skybox.reflectionMap.getSamplerInfo()); + const sampler: Sampler = root.device.getSampler(skybox.reflectionMap.getSamplerInfo()); setter.setTexture('cc_environment', texture); setter.setSampler('cc_environment', sampler); } else { const envmap = skybox.envmap ? skybox.envmap : builtinResMgr.get('default-cube-texture'); if (envmap) { const texture = envmap.getGFXTexture()!; - const sampler = root.device.getSampler(envmap.getSamplerInfo()); + const sampler: Sampler = root.device.getSampler(envmap.getSamplerInfo()); setter.setTexture('cc_environment', texture); setter.setSampler('cc_environment', sampler); } @@ -756,11 +775,11 @@ function setTextureUBOView (setter: WebSetter, camera: Camera | null, cfg: Reado const diffuseMap = skybox.diffuseMap ? skybox.diffuseMap : builtinResMgr.get('default-cube-texture'); if (diffuseMap) { const texture = diffuseMap.getGFXTexture()!; - const sampler = root.device.getSampler(diffuseMap.getSamplerInfo()); + const sampler: Sampler = root.device.getSampler(diffuseMap.getSamplerInfo()); setter.setTexture('cc_diffuseMap', texture); setter.setSampler('cc_diffuseMap', sampler); } - const pointSampler = root.device.getSampler(_samplerPointInfo); + const pointSampler: Sampler = root.device.getSampler(_samplerPointInfo); if (!setter.hasSampler('cc_shadowMap')) { setter.setSampler('cc_shadowMap', pointSampler); } @@ -779,7 +798,7 @@ function getFirstChildLayoutName (lg: LayoutGraphData, parentID: number): string if (lg.numVertices() && parentID !== 0xFFFFFFFF && lg.numChildren(parentID)) { const childNodes = lg.children(parentID); if (childNodes.next().value && childNodes.next().value.target !== lg.nullVertex()) { - const ququeLayoutID = childNodes.next().value.target; + const ququeLayoutID: number = childNodes.next().value.target; return lg.getName(ququeLayoutID); } } @@ -812,14 +831,16 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild addSceneOfCamera (camera: Camera, light: LightInfo, sceneFlags = SceneFlags.NONE, name = 'Camera'): void { const sceneData = new SceneData(camera.scene, camera, sceneFlags, light); - this._renderGraph.addVertex( - RenderGraphValue.Scene, sceneData, name, '', new RenderData(), false, this._vertID, - ); + this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, name, '', new RenderData(), false, this._vertID); const layoutName = this.getLayoutName(); - const scene = cclegacy.director.getScene(); - setCameraUBOValues(this, camera, this._pipeline, - camera.scene ? camera.scene : scene ? scene.renderScene : null, - layoutName); + const scene: Scene = cclegacy.director.getScene(); + setCameraUBOValues( + this, + camera, + this._pipeline, + camera.scene || (scene ? scene.renderScene : null), + layoutName, + ); if (sceneFlags & SceneFlags.SHADOW_CASTER) { setShadowUBOLightView(this, camera, light.light!, light.level, layoutName); } else { @@ -830,31 +851,35 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild } addScene (camera: Camera, sceneFlags = SceneFlags.NONE): void { const sceneData = new SceneData(camera.scene, camera, sceneFlags); - this._renderGraph.addVertex( - RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - ); + this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID); } addSceneCulledByDirectionalLight (camera: Camera, sceneFlags: SceneFlags, light: DirectionalLight, level: number): void { const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, level)); - this._renderGraph.addVertex( - RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - ); + this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID); } addSceneCulledBySpotLight (camera: Camera, sceneFlags: SceneFlags, light: SpotLight): void { const sceneData = new SceneData(camera.scene, camera, sceneFlags, new LightInfo(light, 0)); - this._renderGraph.addVertex( - RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID, - ); + this._renderGraph.addVertex(RenderGraphValue.Scene, sceneData, 'Scene', '', new RenderData(), false, this._vertID); } addFullscreenQuad (material: Material, passID: number, sceneFlags = SceneFlags.NONE, name = 'Quad'): void { this._renderGraph.addVertex( - RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, null), - name, '', new RenderData(), false, this._vertID, + RenderGraphValue.Blit, + new Blit(material, passID, sceneFlags, null), + name, + '', + new RenderData(), + false, + this._vertID, ); const layoutName = this.getLayoutName(); - const scene = cclegacy.director.getScene(); - setCameraUBOValues(this, null, this._pipeline, - scene ? scene.renderScene : null, layoutName); + const scene: Scene | null = cclegacy.director.getScene(); + setCameraUBOValues( + this, + null, + this._pipeline, + scene ? scene.renderScene : null, + layoutName, + ); if (sceneFlags & SceneFlags.SHADOW_CASTER) { // setShadowUBOLightView(this, light.light!, light.level); } else { @@ -865,13 +890,23 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild } addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags = SceneFlags.NONE): void { this._renderGraph.addVertex( - RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, camera), - 'CameraQuad', '', new RenderData(), false, this._vertID, + RenderGraphValue.Blit, + new Blit(material, passID, sceneFlags, camera), + 'CameraQuad', + '', + new RenderData(), + false, + this._vertID, ); const layoutName = this.getLayoutName(); - const scene = cclegacy.director.getScene(); - setCameraUBOValues(this, camera, this._pipeline, - camera.scene ? camera.scene : scene ? scene.renderScene : null, layoutName); + const scene: Scene = cclegacy.director.getScene(); + setCameraUBOValues( + this, + camera, + this._pipeline, + camera.scene || (scene ? scene.renderScene : null), + layoutName, + ); if (sceneFlags & SceneFlags.SHADOW_CASTER) { // setShadowUBOLightView(this, light.light!, light.level); } else { @@ -882,8 +917,13 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild } clearRenderTarget (name: string, color: Color = new Color()): void { this._renderGraph.addVertex( - RenderGraphValue.Clear, [new ClearView(name, ClearFlagBit.COLOR, color)], - 'ClearRenderTarget', '', new RenderData(), false, this._vertID, + RenderGraphValue.Clear, + [new ClearView(name, ClearFlagBit.COLOR, color)], + 'ClearRenderTarget', + '', + new RenderData(), + false, + this._vertID, ); } setViewport (viewport: Viewport): void { @@ -899,8 +939,14 @@ export class WebRenderQueueBuilder extends WebSetter implements RenderQueueBuild } export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassBuilder { - constructor (data: RenderData, renderGraph: RenderGraph, layoutGraph: LayoutGraphData, - vertID: number, subpass: RasterSubpass, pipeline: PipelineSceneData) { + constructor ( + data: RenderData, + renderGraph: RenderGraph, + layoutGraph: LayoutGraphData, + vertID: number, + subpass: RasterSubpass, + pipeline: PipelineSceneData, + ) { super(data, layoutGraph); this._renderGraph = renderGraph; this._layoutGraph = layoutGraph; @@ -908,11 +954,12 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB this._subpass = subpass; this._pipeline = pipeline; - const layoutName = this._renderGraph.component( - RenderGraphComponent.Layout, this._vertID, - ); + const layoutName = this._renderGraph.component(RenderGraphComponent.Layout, this._vertID); this._layoutID = layoutGraph.locateChild(layoutGraph.nullVertex(), layoutName); } + addRenderTarget (name: string, accessType: AccessType, slotName?: string | undefined, loadOp?: LoadOp | undefined, storeOp?: StoreOp | undefined, color?: Color | undefined): void { + throw new Error('Method not implemented.'); + } setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void { throw new Error('Method not implemented.'); } @@ -925,9 +972,7 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB set name (name: string) { this._renderGraph.setName(this._vertID, name); } - addRenderTarget (name: string, accessType: AccessType, slotName: string, loadOp = LoadOp.CLEAR, storeOp = StoreOp.STORE, clearColor = new Color()): void { - throw new Error('Method not implemented.'); - } + addDepthStencil (name: string, accessType: AccessType, depthSlotName = '', stencilSlotName = '', loadOp = LoadOp.CLEAR, storeOp = StoreOp.STORE, depth = 1, stencil = 0, clearFlag = ClearFlagBit.DEPTH_STENCIL): void { throw new Error('Method not implemented.'); } @@ -950,9 +995,7 @@ export class WebRenderSubpassBuilder extends WebSetter implements RenderSubpassB } const queue = new RenderQueue(hint); const data = new RenderData(); - const queueID = this._renderGraph.addVertex( - RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID, - ); + const queueID = this._renderGraph.addVertex(RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID); return new WebRenderQueueBuilder(data, this._renderGraph, this._layoutGraph, queueID, queue, this._pipeline); } get showStatistics (): boolean { @@ -980,9 +1023,7 @@ export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleR this._pass = pass; this._pipeline = pipeline; - const layoutName = this._renderGraph.component( - RenderGraphComponent.Layout, this._vertID, - ); + const layoutName = this._renderGraph.component(RenderGraphComponent.Layout, this._vertID); this._layoutID = layoutGraph.locateChild(layoutGraph.nullVertex(), layoutName); } setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void { @@ -1009,24 +1050,32 @@ export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleR if (loadOp === LoadOp.LOAD) { clearFlag = ClearFlagBit.NONE; } - const view = new RasterView('', - AccessType.WRITE, AttachmentType.RENDER_TARGET, + const view = new RasterView( + '', + AccessType.WRITE, + + AttachmentType.RENDER_TARGET, loadOp, storeOp, clearFlag, - clearColor); + clearColor, + ); this._pass.rasterViews.set(name, view); } addDepthStencil (name: string, loadOp = LoadOp.CLEAR, storeOp = StoreOp.STORE, depth = 1, stencil = 0, clearFlag = ClearFlagBit.DEPTH_STENCIL): void { if (DEBUG) { assert(Boolean(name && this._resourceGraph.contains(name))); } - const view = new RasterView('', - AccessType.WRITE, AttachmentType.DEPTH_STENCIL, + const view = new RasterView( + '', + AccessType.WRITE, + + AttachmentType.DEPTH_STENCIL, loadOp, storeOp, clearFlag, - new Color(depth, stencil, 0, 0)); + new Color(depth, stencil, 0, 0), + ); this._pass.rasterViews.set(name, view); } resolveRenderTarget (source: string, target: string): void { @@ -1075,9 +1124,7 @@ export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleR this._pass.subpassGraph.addVertex(name, new Subpass()); const subpass = new RasterSubpass(subpassID, 1, 0); const data = new RenderData(); - const vertID = this._renderGraph.addVertex( - RenderGraphValue.RasterSubpass, subpass, name, layoutName, data, false, - ); + const vertID = this._renderGraph.addVertex(RenderGraphValue.RasterSubpass, subpass, name, layoutName, data, false); const result = new WebRenderSubpassBuilder(data, this._renderGraph, this._layoutGraph, vertID, subpass, this._pipeline); return result; } @@ -1088,34 +1135,51 @@ export class WebRenderPassBuilder extends WebSetter implements BasicMultisampleR } const queue = new RenderQueue(hint); const data = new RenderData(); - const queueID = this._renderGraph.addVertex( - RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID, - ); + const queueID = this._renderGraph.addVertex(RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID); return new WebRenderQueueBuilder(data, this._renderGraph, this._layoutGraph, queueID, queue, this._pipeline); } addFullscreenQuad (material: Material, passID: number, sceneFlags = SceneFlags.NONE, name = 'FullscreenQuad'): void { const queue = new RenderQueue(QueueHint.RENDER_TRANSPARENT); const queueId = this._renderGraph.addVertex( - RenderGraphValue.Queue, queue, - 'Queue', '', new RenderData(), - false, this._vertID, + RenderGraphValue.Queue, + queue, + 'Queue', + '', + new RenderData(), + false, + this._vertID, ); this._renderGraph.addVertex( - RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, null), - name, '', new RenderData(), false, queueId, + RenderGraphValue.Blit, + new Blit(material, passID, sceneFlags, null), + name, + '', + new RenderData(), + false, + queueId, ); } addCameraQuad (camera: Camera, material: Material, passID: number, sceneFlags: SceneFlags, name = 'CameraQuad'): void { const queue = new RenderQueue(QueueHint.RENDER_TRANSPARENT); const queueId = this._renderGraph.addVertex( - RenderGraphValue.Queue, queue, - 'Queue', '', new RenderData(), false, this._vertID, + RenderGraphValue.Queue, + queue, + 'Queue', + '', + new RenderData(), + false, + this._vertID, ); this._renderGraph.addVertex( - RenderGraphValue.Blit, new Blit(material, passID, sceneFlags, camera), - name, '', new RenderData(), false, queueId, + RenderGraphValue.Blit, + new Blit(material, passID, sceneFlags, camera), + name, + '', + new RenderData(), + false, + queueId, ); } setViewport (viewport: Viewport): void { @@ -1164,7 +1228,15 @@ export class WebComputeQueueBuilder extends WebSetter implements ComputeQueueBui this._renderGraph.addVertex( RenderGraphValue.Dispatch, new Dispatch(material, passID, threadGroupCountX, threadGroupCountY, threadGroupCountZ), - name, '', new RenderData(), false, this._vertID, + name, + + '', + + new RenderData(), + + false, + + this._vertID, ); } private readonly _renderGraph: RenderGraph; @@ -1183,9 +1255,7 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild this._pass = pass; this._pipeline = pipeline; - const layoutName = this._renderGraph.component( - RenderGraphComponent.Layout, this._vertID, - ); + const layoutName = this._renderGraph.component(RenderGraphComponent.Layout, this._vertID); this._layoutID = layoutGraph.locateChild(layoutGraph.nullVertex(), layoutName); } setCustomShaderStages (name: string, stageFlags: ShaderStageFlagBit): void { @@ -1219,9 +1289,7 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild } const queue = new RenderQueue(); const data = new RenderData(); - const queueID = this._renderGraph.addVertex( - RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID, - ); + const queueID = this._renderGraph.addVertex(RenderGraphValue.Queue, queue, '', layoutName, data, false, this._vertID); return new WebComputeQueueBuilder(data, this._renderGraph, this._layoutGraph, queueID, queue, this._pipeline); } private readonly _renderGraph: RenderGraph; @@ -1317,7 +1385,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Framebuffer, renderWindow.framebuffer, - name, desc, + name, + + desc, new ResourceTraits(ResourceResidency.EXTERNAL), new ResourceStates(), new SamplerInfo(), @@ -1326,7 +1396,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Swapchain, new RenderSwapchain(renderWindow.swapchain), - name, desc, + name, + + desc, new ResourceTraits(ResourceResidency.BACKBUFFER), new ResourceStates(), new SamplerInfo(), @@ -1390,7 +1462,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(Filter.LINEAR, Filter.LINEAR, Filter.NONE, Address.CLAMP, Address.CLAMP, Address.CLAMP), @@ -1661,7 +1735,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.ManagedBuffer, new ManagedBuffer(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(), @@ -1681,7 +1757,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(Filter.LINEAR, Filter.LINEAR, Filter.NONE, Address.CLAMP, Address.CLAMP, Address.CLAMP), @@ -1700,7 +1778,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(Filter.POINT, Filter.POINT, Filter.NONE), @@ -1718,7 +1798,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(Filter.POINT, Filter.POINT, Filter.NONE), @@ -1737,7 +1819,9 @@ export class WebPipeline implements BasicPipeline { return this._resourceGraph.addVertex( ResourceGraphValue.Managed, new ManagedResource(), - name, desc, + name, + + desc, new ResourceTraits(residency), new ResourceStates(), new SamplerInfo(Filter.LINEAR, Filter.LINEAR, Filter.NONE, Address.CLAMP, Address.CLAMP, Address.CLAMP), @@ -1769,8 +1853,15 @@ export class WebPipeline implements BasicPipeline { throw new Error('Cannot run without creating rendergraph'); } if (!this._executor) { - this._executor = new Executor(this, this._pipelineUBO, this._device, - this._resourceGraph, this.layoutGraph, this.width, this.height); + this._executor = new Executor( + this, + this._pipelineUBO, + this._device, + this._resourceGraph, + this.layoutGraph, + this.width, + this.height, + ); } this._executor.resize(this.width, this.height); this._executor.execute(this._renderGraph); @@ -1823,9 +1914,7 @@ export class WebPipeline implements BasicPipeline { pass.quality = quality; const data = new RenderData(); - const vertID = this._renderGraph!.addVertex( - RenderGraphValue.RasterPass, pass, name, layoutName, data, false, - ); + const vertID = this._renderGraph!.addVertex(RenderGraphValue.RasterPass, pass, name, layoutName, data, false); const result = new WebRenderPassBuilder(data, this._renderGraph!, this._layoutGraph, this._resourceGraph, vertID, pass, this._pipelineSceneData); this._updateRasterPassConstants(result, width, height, isEnableEffect() ? layoutName : 'default'); initGlobalDescBinding(data, layoutName); @@ -1860,8 +1949,8 @@ export class WebPipeline implements BasicPipeline { } protected _updateRasterPassConstants (setter: WebSetter, width: number, height: number, layoutName = 'default'): void { - const director = cclegacy.director; - const root = director.root; + const director: Director = cclegacy.director; + const root: Root = director.root!; const shadingWidth = width; const shadingHeight = height; const pipeline = root.pipeline as WebPipeline; @@ -1888,7 +1977,7 @@ export class WebPipeline implements BasicPipeline { if (debugView) { if (setter.hasUniform(uniformOffset)) { const debugPackVec: number[] = [debugView.singleMode as number, 0.0, 0.0, 0.0]; - for (let i = DebugViewCompositeType.DIRECT_DIFFUSE as number; i < DebugViewCompositeType.MAX_BIT_COUNT; i++) { + for (let i = DebugViewCompositeType.DIRECT_DIFFUSE as number; i < (DebugViewCompositeType.MAX_BIT_COUNT as number); i++) { const idx = i >> 3; const bit = i % 8; debugPackVec[idx + 1] += (debugView.isCompositeModeEnabled(i) ? 1.0 : 0.0) * (10.0 ** bit); From 46387dfc9edaa9fd91d7eeb4a80a34750fce7433 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 18 Jul 2023 10:06:06 +0800 Subject: [PATCH 53/57] fix lint --- cocos/rendering/custom/web-pipeline.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/rendering/custom/web-pipeline.ts b/cocos/rendering/custom/web-pipeline.ts index 1b30db086fb..c1bac8ca455 100644 --- a/cocos/rendering/custom/web-pipeline.ts +++ b/cocos/rendering/custom/web-pipeline.ts @@ -26,7 +26,7 @@ import { systemInfo } from 'pal/system-info'; import { DEBUG } from 'internal:constants'; import { Buffer, DescriptorSetLayout, Device, Feature, Format, FormatFeatureBit, Sampler, Swapchain, Texture, ClearFlagBit, DescriptorSet, deviceManager, Viewport, API, CommandBuffer, Type, SamplerInfo, Filter, Address, DescriptorSetInfo, LoadOp, StoreOp, ShaderStageFlagBit, BufferInfo, TextureInfo, UniformBlock, ResolveMode, SampleCount, Color } from '../../gfx'; -import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy, IVec4Like, IMat4Like, IVec2Like } from '../../core'; +import { Mat4, Quat, toRadian, Vec2, Vec3, Vec4, assert, macro, cclegacy, IVec4Like, IMat4Like, IVec2Like, Color as CoreColor } from '../../core'; import { AccessType, AttachmentType, CopyPair, LightInfo, LightingMode, MovePair, QueueHint, ResolvePair, ResourceDimension, ResourceFlags, ResourceResidency, SceneFlags, UpdateFrequency } from './types'; import { ComputeView, RasterView, Blit, ClearView, ComputePass, CopyPass, Dispatch, ManagedBuffer, ManagedResource, MovePass, RasterPass, RasterSubpass, RenderData, RenderGraph, RenderGraphComponent, RenderGraphValue, RenderQueue, RenderSwapchain, ResourceDesc, ResourceGraph, ResourceGraphValue, ResourceStates, ResourceTraits, SceneData, Subpass } from './render-graph'; import { ComputePassBuilder, ComputeQueueBuilder, ComputeSubpassBuilder, BasicPipeline, PipelineBuilder, RenderPassBuilder, RenderQueueBuilder, RenderSubpassBuilder, PipelineType, BasicRenderPassBuilder, PipelineCapabilities, BasicMultisampleRenderPassBuilder } from './pipeline'; @@ -216,7 +216,7 @@ export class WebSetter { public setColor (name: string, color: Color, idx = 0): void { this._applyCurrConstantBuffer(name, color, Type.FLOAT4, idx); } - public offsetColor (color: Color, offset: number): void { + public offsetColor (color: Color | CoreColor, offset: number): void { this._copyToBuffer(color, offset, Type.FLOAT4); } public setVec4 (name: string, vec: Vec4, idx = 0): void { From 56d6339e6bccd3ebfb9bed59abaa9a899faa2924 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Tue, 18 Jul 2023 16:20:47 +0800 Subject: [PATCH 54/57] add gpu driven --- cocos/rendering/custom/types.ts | 9 ++++++++ .../pipeline/custom/NativePipelineFwd.h | 1 + .../pipeline/custom/NativePipelineTypes.cpp | 17 +++++++++++++- .../pipeline/custom/NativePipelineTypes.h | 23 +++++++++++++++++++ .../pipeline/custom/RenderCommonJsb.cpp | 21 +++++++++++++++++ .../custom/RenderCommonSerialization.h | 6 +++++ .../pipeline/custom/RenderCommonTypes.cpp | 17 ++++++++++++-- .../pipeline/custom/RenderCommonTypes.h | 4 ++++ 8 files changed, 95 insertions(+), 3 deletions(-) diff --git a/cocos/rendering/custom/types.ts b/cocos/rendering/custom/types.ts index d09e3b8a9fe..7e88c420aff 100644 --- a/cocos/rendering/custom/types.ts +++ b/cocos/rendering/custom/types.ts @@ -432,6 +432,9 @@ export class CopyPair { targetMostDetailedMip: number; targetFirstSlice: number; targetPlaneSlice: number; + sourceOffset = 0; + targetOffset = 0; + bufferSize = 0; } export class UploadPair { @@ -649,6 +652,9 @@ export function saveCopyPair (ar: OutputArchive, v: CopyPair): void { ar.writeNumber(v.targetMostDetailedMip); ar.writeNumber(v.targetFirstSlice); ar.writeNumber(v.targetPlaneSlice); + ar.writeNumber(v.sourceOffset); + ar.writeNumber(v.targetOffset); + ar.writeNumber(v.bufferSize); } export function loadCopyPair (ar: InputArchive, v: CopyPair): void { @@ -662,6 +668,9 @@ export function loadCopyPair (ar: InputArchive, v: CopyPair): void { v.targetMostDetailedMip = ar.readNumber(); v.targetFirstSlice = ar.readNumber(); v.targetPlaneSlice = ar.readNumber(); + v.sourceOffset = ar.readNumber(); + v.targetOffset = ar.readNumber(); + v.bufferSize = ar.readNumber(); } export function saveMovePair (ar: OutputArchive, v: MovePair): void { diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h index 846d97ac32d..b059e3fd307 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineFwd.h @@ -50,6 +50,7 @@ class NativeMultisampleRenderPassBuilder; class NativeComputeQueueBuilder; class NativeComputePassBuilder; struct RenderInstancingQueue; +struct RenderBatchingQueue; struct DrawInstance; struct RenderDrawQueue; struct NativeRenderQueue; diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp index d8de417ef46..dca32301121 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.cpp @@ -49,6 +49,15 @@ RenderInstancingQueue::RenderInstancingQueue(RenderInstancingQueue const& rhs, c passInstances(rhs.passInstances, alloc), instanceBuffers(rhs.instanceBuffers, alloc) {} +RenderBatchingQueue::RenderBatchingQueue(const allocator_type& alloc) noexcept +: batches(alloc) {} + +RenderBatchingQueue::RenderBatchingQueue(RenderBatchingQueue&& rhs, const allocator_type& alloc) +: batches(std::move(rhs.batches), alloc) {} + +RenderBatchingQueue::RenderBatchingQueue(RenderBatchingQueue const& rhs, const allocator_type& alloc) +: batches(rhs.batches, alloc) {} + RenderDrawQueue::RenderDrawQueue(const allocator_type& alloc) noexcept : instances(alloc) {} @@ -62,13 +71,17 @@ NativeRenderQueue::NativeRenderQueue(const allocator_type& alloc) noexcept : opaqueQueue(alloc), transparentQueue(alloc), opaqueInstancingQueue(alloc), - transparentInstancingQueue(alloc) {} + transparentInstancingQueue(alloc), + opaqueBatchingQueue(alloc), + transparentBatchingQueue(alloc) {} NativeRenderQueue::NativeRenderQueue(SceneFlags sceneFlagsIn, uint32_t subpassOrPassLayoutIDIn, const allocator_type& alloc) noexcept : opaqueQueue(alloc), transparentQueue(alloc), opaqueInstancingQueue(alloc), transparentInstancingQueue(alloc), + opaqueBatchingQueue(alloc), + transparentBatchingQueue(alloc), sceneFlags(sceneFlagsIn), subpassOrPassLayoutID(subpassOrPassLayoutIDIn) {} @@ -77,6 +90,8 @@ NativeRenderQueue::NativeRenderQueue(NativeRenderQueue&& rhs, const allocator_ty transparentQueue(std::move(rhs.transparentQueue), alloc), opaqueInstancingQueue(std::move(rhs.opaqueInstancingQueue), alloc), transparentInstancingQueue(std::move(rhs.transparentInstancingQueue), alloc), + opaqueBatchingQueue(std::move(rhs.opaqueBatchingQueue), alloc), + transparentBatchingQueue(std::move(rhs.transparentBatchingQueue), alloc), sceneFlags(rhs.sceneFlags), subpassOrPassLayoutID(rhs.subpassOrPassLayoutID) {} diff --git a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h index b21235bc46b..87d1282869d 100644 --- a/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h +++ b/native/cocos/renderer/pipeline/custom/NativePipelineTypes.h @@ -796,6 +796,27 @@ struct RenderInstancingQueue { ccstd::pmr::vector> instanceBuffers; }; +struct RenderBatchingQueue { + using allocator_type = boost::container::pmr::polymorphic_allocator; + allocator_type get_allocator() const noexcept { // NOLINT + return {batches.get_allocator().resource()}; + } + + RenderBatchingQueue(const allocator_type& alloc) noexcept; // NOLINT + RenderBatchingQueue(RenderBatchingQueue&& rhs, const allocator_type& alloc); + RenderBatchingQueue(RenderBatchingQueue const& rhs, const allocator_type& alloc); + + RenderBatchingQueue(RenderBatchingQueue&& rhs) noexcept = default; + RenderBatchingQueue(RenderBatchingQueue const& rhs) = delete; + RenderBatchingQueue& operator=(RenderBatchingQueue&& rhs) = default; + RenderBatchingQueue& operator=(RenderBatchingQueue const& rhs) = default; + + static void recordCommandBuffer(gfx::Device *device, const scene::Camera *camera, + gfx::RenderPass *renderPass, gfx::CommandBuffer *cmdBuffer, SceneFlags sceneFlags); + + ccstd::pmr::vector batches; +}; + struct DrawInstance { const scene::SubModel* subModel{nullptr}; uint32_t priority{0}; @@ -853,6 +874,8 @@ struct NativeRenderQueue { RenderDrawQueue transparentQueue; RenderInstancingQueue opaqueInstancingQueue; RenderInstancingQueue transparentInstancingQueue; + RenderBatchingQueue opaqueBatchingQueue; + RenderBatchingQueue transparentBatchingQueue; SceneFlags sceneFlags{SceneFlags::NONE}; uint32_t subpassOrPassLayoutID{0xFFFFFFFF}; }; diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp index 9bb23563b0b..b60875af911 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderCommonJsb.cpp @@ -165,6 +165,15 @@ bool nativevalue_to_se(const cc::render::CopyPair &from, se::Value &to, se::Obje nativevalue_to_se(from.targetPlaneSlice, tmp, ctx); obj->setProperty("targetPlaneSlice", tmp); + nativevalue_to_se(from.sourceOffset, tmp, ctx); + obj->setProperty("sourceOffset", tmp); + + nativevalue_to_se(from.targetOffset, tmp, ctx); + obj->setProperty("targetOffset", tmp); + + nativevalue_to_se(from.bufferSize, tmp, ctx); + obj->setProperty("bufferSize", tmp); + to.setObject(obj); return true; } @@ -400,6 +409,18 @@ bool sevalue_to_native(const se::Value &from, cc::render:: if(!field.isNullOrUndefined()) { ok &= sevalue_to_native(field, &(to->targetPlaneSlice), ctx); } + obj->getProperty("sourceOffset", &field, true); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->sourceOffset), ctx); + } + obj->getProperty("targetOffset", &field, true); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->targetOffset), ctx); + } + obj->getProperty("bufferSize", &field, true); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->bufferSize), ctx); + } return ok; } diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h b/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h index 49fa456c4cd..070eef8a9f8 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonSerialization.h @@ -130,6 +130,9 @@ inline void save(OutputArchive& ar, const CopyPair& v) { save(ar, v.targetMostDetailedMip); save(ar, v.targetFirstSlice); save(ar, v.targetPlaneSlice); + save(ar, v.sourceOffset); + save(ar, v.targetOffset); + save(ar, v.bufferSize); } inline void load(InputArchive& ar, CopyPair& v) { @@ -143,6 +146,9 @@ inline void load(InputArchive& ar, CopyPair& v) { load(ar, v.targetMostDetailedMip); load(ar, v.targetFirstSlice); load(ar, v.targetPlaneSlice); + load(ar, v.sourceOffset); + load(ar, v.targetOffset); + load(ar, v.bufferSize); } inline void save(OutputArchive& ar, const MovePair& v) { diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp index 1f556cf1058..ad6ef4ed792 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.cpp @@ -75,6 +75,13 @@ CopyPair::CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uin targetFirstSlice(targetFirstSliceIn), targetPlaneSlice(targetPlaneSliceIn) {} +CopyPair::CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t sourceOffsetIn, uint32_t targetOffsetIn, uint32_t bufferSizeIn, const allocator_type& alloc) noexcept // NOLINT +: source(std::move(sourceIn), alloc), + target(std::move(targetIn), alloc), + sourceOffset(sourceOffsetIn), + targetOffset(targetOffsetIn), + bufferSize(bufferSizeIn) {} + CopyPair::CopyPair(CopyPair&& rhs, const allocator_type& alloc) : source(std::move(rhs.source), alloc), target(std::move(rhs.target), alloc), @@ -85,7 +92,10 @@ CopyPair::CopyPair(CopyPair&& rhs, const allocator_type& alloc) sourcePlaneSlice(rhs.sourcePlaneSlice), targetMostDetailedMip(rhs.targetMostDetailedMip), targetFirstSlice(rhs.targetFirstSlice), - targetPlaneSlice(rhs.targetPlaneSlice) {} + targetPlaneSlice(rhs.targetPlaneSlice), + sourceOffset(rhs.sourceOffset), + targetOffset(rhs.targetOffset), + bufferSize(rhs.bufferSize) {} CopyPair::CopyPair(CopyPair const& rhs, const allocator_type& alloc) : source(rhs.source, alloc), @@ -97,7 +107,10 @@ CopyPair::CopyPair(CopyPair const& rhs, const allocator_type& alloc) sourcePlaneSlice(rhs.sourcePlaneSlice), targetMostDetailedMip(rhs.targetMostDetailedMip), targetFirstSlice(rhs.targetFirstSlice), - targetPlaneSlice(rhs.targetPlaneSlice) {} + targetPlaneSlice(rhs.targetPlaneSlice), + sourceOffset(rhs.sourceOffset), + targetOffset(rhs.targetOffset), + bufferSize(rhs.bufferSize) {} UploadPair::UploadPair(const allocator_type& alloc) noexcept : target(alloc) {} diff --git a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h index eb6dfe6a9b3..c17fe2c50c7 100644 --- a/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h +++ b/native/cocos/renderer/pipeline/custom/RenderCommonTypes.h @@ -346,6 +346,7 @@ struct CopyPair { CopyPair(const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; // NOLINT CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t mipLevelsIn, uint32_t numSlicesIn, uint32_t sourceMostDetailedMipIn, uint32_t sourceFirstSliceIn, uint32_t sourcePlaneSliceIn, uint32_t targetMostDetailedMipIn, uint32_t targetFirstSliceIn, uint32_t targetPlaneSliceIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; + CopyPair(ccstd::pmr::string sourceIn, ccstd::pmr::string targetIn, uint32_t sourceOffsetIn, uint32_t targetOffsetIn, uint32_t bufferSizeIn, const allocator_type& alloc = boost::container::pmr::get_default_resource()) noexcept; CopyPair(CopyPair&& rhs, const allocator_type& alloc); CopyPair(CopyPair const& rhs, const allocator_type& alloc); @@ -364,6 +365,9 @@ struct CopyPair { uint32_t targetMostDetailedMip{0}; uint32_t targetFirstSlice{0}; uint32_t targetPlaneSlice{0}; + uint32_t sourceOffset{0}; + uint32_t targetOffset{0}; + uint32_t bufferSize{0}; }; struct UploadPair { From 5f6ac06d6e10e09f1ee166965b3a537b433f22b3 Mon Sep 17 00:00:00 2001 From: Zach Lee Date: Tue, 18 Jul 2023 18:30:12 +0800 Subject: [PATCH 55/57] Sync develop indirect draw. (#153) --- cocos/asset/assets/rendering-sub-mesh.ts | 2 +- cocos/gfx/base/define.ts | 2 - cocos/gfx/base/input-assembler.ts | 9 - cocos/gfx/webgl/webgl-buffer.ts | 1 - cocos/gfx/webgl/webgl-commands.ts | 84 +------- cocos/gfx/webgl/webgl-gpu-objects.ts | 5 - cocos/gfx/webgl/webgl-input-assembler.ts | 8 - cocos/gfx/webgl2/webgl2-buffer.ts | 2 - cocos/gfx/webgl2/webgl2-commands.ts | 188 +++++------------ cocos/gfx/webgl2/webgl2-gpu-objects.ts | 2 - cocos/gfx/webgl2/webgl2-input-assembler.ts | 8 - native/cocos/core/assets/RenderingSubMesh.cpp | 1 - .../renderer/gfx-agent/CommandBufferAgent.cpp | 53 +++++ .../renderer/gfx-agent/CommandBufferAgent.h | 3 + .../gfx-agent/InputAssemblerAgent.cpp | 3 - .../renderer/gfx-base/GFXCommandBuffer.h | 3 + .../cocos/renderer/gfx-base/GFXDef-common.h | 25 ++- native/cocos/renderer/gfx-base/GFXDef.cpp | 13 ++ native/cocos/renderer/gfx-base/GFXDef.h | 2 + .../renderer/gfx-base/GFXInputAssembler.cpp | 20 +- .../renderer/gfx-base/GFXInputAssembler.h | 4 - .../renderer/gfx-empty/EmptyCommandBuffer.cpp | 9 + .../renderer/gfx-empty/EmptyCommandBuffer.h | 3 + .../cocos/renderer/gfx-gles2/GLES2Buffer.cpp | 4 - .../renderer/gfx-gles2/GLES2CommandBuffer.cpp | 20 ++ .../renderer/gfx-gles2/GLES2CommandBuffer.h | 3 + .../renderer/gfx-gles2/GLES2Commands.cpp | 54 ++--- .../renderer/gfx-gles2/GLES2GPUObjects.h | 2 - .../gfx-gles2/GLES2InputAssembler.cpp | 4 - .../gfx-gles2/GLES2PrimaryCommandBuffer.cpp | 19 ++ .../gfx-gles2/GLES2PrimaryCommandBuffer.h | 3 + .../cocos/renderer/gfx-gles3/GLES3Buffer.cpp | 6 - .../renderer/gfx-gles3/GLES3CommandBuffer.cpp | 18 ++ .../renderer/gfx-gles3/GLES3CommandBuffer.h | 3 + .../renderer/gfx-gles3/GLES3Commands.cpp | 133 ++++++++---- .../cocos/renderer/gfx-gles3/GLES3Commands.h | 11 + .../cocos/renderer/gfx-gles3/GLES3Device.cpp | 1 + .../renderer/gfx-gles3/GLES3GPUObjects.h | 5 +- .../gfx-gles3/GLES3InputAssembler.cpp | 4 - .../gfx-gles3/GLES3PrimaryCommandBuffer.cpp | 27 +++ .../gfx-gles3/GLES3PrimaryCommandBuffer.h | 3 + native/cocos/renderer/gfx-metal/MTLBuffer.h | 7 - native/cocos/renderer/gfx-metal/MTLBuffer.mm | 86 +------- .../renderer/gfx-metal/MTLCommandBuffer.h | 4 + .../renderer/gfx-metal/MTLCommandBuffer.mm | 195 +++++++++--------- .../gfx-validator/BufferValidator.cpp | 12 -- .../gfx-validator/CommandBufferValidator.cpp | 51 +++++ .../gfx-validator/CommandBufferValidator.h | 3 + .../gfx-validator/InputAssemblerValidator.cpp | 7 - native/cocos/renderer/gfx-vulkan/VKBuffer.cpp | 6 - .../renderer/gfx-vulkan/VKCommandBuffer.cpp | 157 ++++++++------ .../renderer/gfx-vulkan/VKCommandBuffer.h | 3 + .../cocos/renderer/gfx-vulkan/VKCommands.cpp | 38 +--- native/cocos/renderer/gfx-vulkan/VKDevice.cpp | 2 + .../cocos/renderer/gfx-vulkan/VKGPUObjects.h | 5 - .../renderer/gfx-vulkan/VKInputAssembler.cpp | 11 - .../pipeline/custom/NativeExecutor.cpp | 21 +- .../renderer/pipeline/xr/ar/ARBackground.cpp | 20 +- native/tools/swig-config/gfx.i | 3 +- 59 files changed, 663 insertions(+), 738 deletions(-) diff --git a/cocos/asset/assets/rendering-sub-mesh.ts b/cocos/asset/assets/rendering-sub-mesh.ts index a648dc6a3ea..857a7161d3a 100644 --- a/cocos/asset/assets/rendering-sub-mesh.ts +++ b/cocos/asset/assets/rendering-sub-mesh.ts @@ -144,7 +144,7 @@ export class RenderingSubMesh { this._indexBuffer = indexBuffer; this._indirectBuffer = indirectBuffer; this._primitiveMode = primitiveMode; - this._iaInfo = new InputAssemblerInfo(attributes, vertexBuffers, indexBuffer, indirectBuffer); + this._iaInfo = new InputAssemblerInfo(attributes, vertexBuffers, indexBuffer); this._isOwnerOfIndexBuffer = isOwnerOfIndexBuffer; } diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index 53eeb4062cb..66ea06c825c 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -1502,14 +1502,12 @@ export class InputAssemblerInfo { public attributes: Attribute[] = [], public vertexBuffers: Buffer[] = [], public indexBuffer: Buffer | null = null, - public indirectBuffer: Buffer | null = null, ) {} public copy (info: Readonly): InputAssemblerInfo { deepCopy(this.attributes, info.attributes, Attribute); this.vertexBuffers = info.vertexBuffers.slice(); this.indexBuffer = info.indexBuffer; - this.indirectBuffer = info.indirectBuffer; return this; } } diff --git a/cocos/gfx/base/input-assembler.ts b/cocos/gfx/base/input-assembler.ts index 84312b9aa3b..ca088ee2a4f 100644 --- a/cocos/gfx/base/input-assembler.ts +++ b/cocos/gfx/base/input-assembler.ts @@ -55,14 +55,6 @@ export abstract class InputAssembler extends GFXObject { return this._indexBuffer; } - /** - * @en Get the indirect buffer, if present. - * @zh 间接绘制缓冲。 - */ - get indirectBuffer (): Buffer | null { - return this._indirectBuffer; - } - /** * @en Get hash of current attributes. * @zh 获取顶点属性数组的哈希值。 @@ -169,7 +161,6 @@ export abstract class InputAssembler extends GFXObject { protected _vertexBuffers: Buffer[] = []; protected _indexBuffer: Buffer | null = null; - protected _indirectBuffer: Buffer | null = null; protected _drawInfo = new DrawInfo(); diff --git a/cocos/gfx/webgl/webgl-buffer.ts b/cocos/gfx/webgl/webgl-buffer.ts index 9f6c308dc61..a4533b76dea 100644 --- a/cocos/gfx/webgl/webgl-buffer.ts +++ b/cocos/gfx/webgl/webgl-buffer.ts @@ -83,7 +83,6 @@ export class WebGLBuffer extends Buffer { stride: this._stride, buffer: null, vf32: null, - indirects: new WebGLIndirectDrawInfos(), glTarget: 0, glBuffer: null, }; diff --git a/cocos/gfx/webgl/webgl-commands.ts b/cocos/gfx/webgl/webgl-commands.ts index f64ea3cc4ea..7355454b65b 100644 --- a/cocos/gfx/webgl/webgl-commands.ts +++ b/cocos/gfx/webgl/webgl-commands.ts @@ -782,12 +782,6 @@ export function WebGLCmdFuncUpdateBuffer ( } else { gpuBuffer.vf32!.set(new Float32Array(buffer as ArrayBuffer), offset / Float32Array.BYTES_PER_ELEMENT); } - } else if (gpuBuffer.usage & BufferUsageBit.INDIRECT) { - gpuBuffer.indirects.clearDraws(); - const drawInfos = (buffer as IndirectBuffer).drawInfos; - for (let i = 0; i < drawInfos.length; ++i) { - gpuBuffer.indirects.setDrawInfo(offset + i, drawInfos[i]); - } } else { const buff = buffer as ArrayBuffer; const { gl } = device; @@ -2590,83 +2584,7 @@ export function WebGLCmdFuncDraw (device: WebGLDevice, drawInfo: Readonly 0) { const offset = drawInfo.firstIndex * indexBuffer.stride; diff --git a/cocos/gfx/webgl/webgl-gpu-objects.ts b/cocos/gfx/webgl/webgl-gpu-objects.ts index 8abff6d139d..83350acaa67 100644 --- a/cocos/gfx/webgl/webgl-gpu-objects.ts +++ b/cocos/gfx/webgl/webgl-gpu-objects.ts @@ -131,7 +131,6 @@ export interface IWebGLGPUBuffer { buffer: ArrayBufferView | null; vf32: Float32Array | null; - indirects: WebGLIndirectDrawInfos; } export interface IWebGLGPUTexture { @@ -309,7 +308,6 @@ export interface IWebGLGPUInputAssembler { attributes: Attribute[]; gpuVertexBuffers: IWebGLGPUBuffer[]; gpuIndexBuffer: IWebGLGPUBuffer | null; - gpuIndirectBuffer: IWebGLGPUBuffer | null; glAttribs: IWebGLAttrib[]; glIndexType: GLenum; @@ -430,7 +428,6 @@ export class IWebGLBlitManager { stride: 4 * Float32Array.BYTES_PER_ELEMENT, buffer: null, vf32: null, - indirects: new WebGLIndirectDrawInfos(), glTarget: 0, glBuffer: null, }; @@ -448,7 +445,6 @@ export class IWebGLBlitManager { attributes: [new Attribute(`a_position`, Format.RG32F), new Attribute(`a_texCoord`, Format.RG32F)], gpuVertexBuffers: [this._gpuVertexBuffer], gpuIndexBuffer: null, - gpuIndirectBuffer: null, glAttribs: [], glIndexType: 0, @@ -480,7 +476,6 @@ export class IWebGLBlitManager { stride: 8 * Float32Array.BYTES_PER_ELEMENT, buffer: this._uniformBuffer, vf32: null, - indirects: new WebGLIndirectDrawInfos(), glTarget: 0, glBuffer: null, }; diff --git a/cocos/gfx/webgl/webgl-input-assembler.ts b/cocos/gfx/webgl/webgl-input-assembler.ts index 58a188c6a4e..4208609de41 100644 --- a/cocos/gfx/webgl/webgl-input-assembler.ts +++ b/cocos/gfx/webgl/webgl-input-assembler.ts @@ -59,8 +59,6 @@ export class WebGLInputAssembler extends InputAssembler { this._drawInfo.instanceCount = 0; this._drawInfo.firstInstance = 0; - this._indirectBuffer = info.indirectBuffer || null; - const gpuVertexBuffers: IWebGLGPUBuffer[] = new Array(info.vertexBuffers.length); for (let i = 0; i < info.vertexBuffers.length; ++i) { const vb = info.vertexBuffers[i] as WebGLBuffer; @@ -85,16 +83,10 @@ export class WebGLInputAssembler extends InputAssembler { } } - let gpuIndirectBuffer: IWebGLGPUBuffer | null = null; - if (info.indirectBuffer) { - gpuIndirectBuffer = (info.indirectBuffer as WebGLBuffer).gpuBuffer; - } - this._gpuInputAssembler = { attributes: info.attributes, gpuVertexBuffers, gpuIndexBuffer, - gpuIndirectBuffer, glAttribs: [], glIndexType, diff --git a/cocos/gfx/webgl2/webgl2-buffer.ts b/cocos/gfx/webgl2/webgl2-buffer.ts index a9f868dd156..53fbffabcc0 100644 --- a/cocos/gfx/webgl2/webgl2-buffer.ts +++ b/cocos/gfx/webgl2/webgl2-buffer.ts @@ -58,7 +58,6 @@ export class WebGL2Buffer extends Buffer { size: this._size, stride: this._stride, buffer: null, - indirects: buffer.gpuBuffer.indirects, glTarget: buffer.gpuBuffer.glTarget, glBuffer: buffer.gpuBuffer.glBuffer, glOffset: info.offset, @@ -77,7 +76,6 @@ export class WebGL2Buffer extends Buffer { size: this._size, stride: this._stride, buffer: null, - indirects: new WebGL2IndirectDrawInfos(), glTarget: 0, glBuffer: null, glOffset: 0, diff --git a/cocos/gfx/webgl2/webgl2-commands.ts b/cocos/gfx/webgl2/webgl2-commands.ts index 80f4caab35c..698558c8a6f 100644 --- a/cocos/gfx/webgl2/webgl2-commands.ts +++ b/cocos/gfx/webgl2/webgl2-commands.ts @@ -974,77 +974,69 @@ export function WebGL2CmdFuncUpdateBuffer ( offset: number, size: number, ): void { - if (gpuBuffer.usage & BufferUsageBit.INDIRECT) { - gpuBuffer.indirects.clearDraws(); - const drawInfos = (buffer as IndirectBuffer).drawInfos; - for (let i = 0; i < drawInfos.length; ++i) { - gpuBuffer.indirects.setDrawInfo(offset + i, drawInfos[i]); - } - } else { - const buff = buffer as ArrayBuffer; - const { gl } = device; - const cache = device.stateCache; - - switch (gpuBuffer.glTarget) { - case gl.ARRAY_BUFFER: { - if (device.extensions.useVAO) { - if (cache.glVAO) { - gl.bindVertexArray(null); - cache.glVAO = null; - } - } - gfxStateCache.gpuInputAssembler = null; + const buff = buffer as ArrayBuffer; + const { gl } = device; + const cache = device.stateCache; - if (cache.glArrayBuffer !== gpuBuffer.glBuffer) { - gl.bindBuffer(gl.ARRAY_BUFFER, gpuBuffer.glBuffer); - cache.glArrayBuffer = gpuBuffer.glBuffer; + switch (gpuBuffer.glTarget) { + case gl.ARRAY_BUFFER: { + if (device.extensions.useVAO) { + if (cache.glVAO) { + gl.bindVertexArray(null); + cache.glVAO = null; } + } + gfxStateCache.gpuInputAssembler = null; - if (size === buff.byteLength) { - gl.bufferSubData(gpuBuffer.glTarget, offset, buff); - } else { - gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size)); - } - break; + if (cache.glArrayBuffer !== gpuBuffer.glBuffer) { + gl.bindBuffer(gl.ARRAY_BUFFER, gpuBuffer.glBuffer); + cache.glArrayBuffer = gpuBuffer.glBuffer; } - case gl.ELEMENT_ARRAY_BUFFER: { - if (device.extensions.useVAO) { - if (cache.glVAO) { - gl.bindVertexArray(null); - cache.glVAO = null; - } - } - gfxStateCache.gpuInputAssembler = null; - if (cache.glElementArrayBuffer !== gpuBuffer.glBuffer) { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gpuBuffer.glBuffer); - cache.glElementArrayBuffer = gpuBuffer.glBuffer; + if (size === buff.byteLength) { + gl.bufferSubData(gpuBuffer.glTarget, offset, buff); + } else { + gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size)); + } + break; + } + case gl.ELEMENT_ARRAY_BUFFER: { + if (device.extensions.useVAO) { + if (cache.glVAO) { + gl.bindVertexArray(null); + cache.glVAO = null; } + } + gfxStateCache.gpuInputAssembler = null; - if (size === buff.byteLength) { - gl.bufferSubData(gpuBuffer.glTarget, offset, buff); - } else { - gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size)); - } - break; + if (cache.glElementArrayBuffer !== gpuBuffer.glBuffer) { + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gpuBuffer.glBuffer); + cache.glElementArrayBuffer = gpuBuffer.glBuffer; } - case gl.UNIFORM_BUFFER: { - if (cache.glUniformBuffer !== gpuBuffer.glBuffer) { - gl.bindBuffer(gl.UNIFORM_BUFFER, gpuBuffer.glBuffer); - cache.glUniformBuffer = gpuBuffer.glBuffer; - } - if (size === buff.byteLength) { - gl.bufferSubData(gpuBuffer.glTarget, offset, buff); - } else { - gl.bufferSubData(gpuBuffer.glTarget, offset, new Float32Array(buff, 0, size / 4)); - } - break; + if (size === buff.byteLength) { + gl.bufferSubData(gpuBuffer.glTarget, offset, buff); + } else { + gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size)); } - default: { - error('Unsupported BufferType, update buffer failed.'); + break; + } + case gl.UNIFORM_BUFFER: { + if (cache.glUniformBuffer !== gpuBuffer.glBuffer) { + gl.bindBuffer(gl.UNIFORM_BUFFER, gpuBuffer.glBuffer); + cache.glUniformBuffer = gpuBuffer.glBuffer; } + + if (size === buff.byteLength) { + gl.bufferSubData(gpuBuffer.glTarget, offset, buff); + } else { + gl.bufferSubData(gpuBuffer.glTarget, offset, new Float32Array(buff, 0, size / 4)); } + break; + } + default: { + error('Unsupported BufferType, update buffer failed.'); + } } } @@ -2649,83 +2641,7 @@ export function WebGL2CmdFuncDraw (device: WebGL2Device, drawInfo: Readonly 0) { const offset = drawInfo.firstIndex * indexBuffer.stride; diff --git a/cocos/gfx/webgl2/webgl2-gpu-objects.ts b/cocos/gfx/webgl2/webgl2-gpu-objects.ts index 1cdec040420..4204d6efb1d 100644 --- a/cocos/gfx/webgl2/webgl2-gpu-objects.ts +++ b/cocos/gfx/webgl2/webgl2-gpu-objects.ts @@ -119,7 +119,6 @@ export interface IWebGL2GPUBuffer { glOffset: number; buffer: ArrayBufferView | null; - indirects: WebGL2IndirectDrawInfos; } export interface IWebGL2GPUTexture { @@ -315,7 +314,6 @@ export interface IWebGL2GPUInputAssembler { attributes: Attribute[]; gpuVertexBuffers: IWebGL2GPUBuffer[]; gpuIndexBuffer: IWebGL2GPUBuffer | null; - gpuIndirectBuffer: IWebGL2GPUBuffer | null; glAttribs: IWebGL2Attrib[]; glIndexType: GLenum; diff --git a/cocos/gfx/webgl2/webgl2-input-assembler.ts b/cocos/gfx/webgl2/webgl2-input-assembler.ts index ec1e5566d9f..0b927925d9f 100644 --- a/cocos/gfx/webgl2/webgl2-input-assembler.ts +++ b/cocos/gfx/webgl2/webgl2-input-assembler.ts @@ -59,8 +59,6 @@ export class WebGL2InputAssembler extends InputAssembler { this._drawInfo.instanceCount = 0; this._drawInfo.firstInstance = 0; - this._indirectBuffer = info.indirectBuffer || null; - const gpuVertexBuffers: IWebGL2GPUBuffer[] = new Array(info.vertexBuffers.length); for (let i = 0; i < info.vertexBuffers.length; ++i) { const vb = info.vertexBuffers[i] as WebGL2Buffer; @@ -85,16 +83,10 @@ export class WebGL2InputAssembler extends InputAssembler { } } - let gpuIndirectBuffer: IWebGL2GPUBuffer | null = null; - if (info.indirectBuffer) { - gpuIndirectBuffer = (info.indirectBuffer as WebGL2Buffer).gpuBuffer; - } - this._gpuInputAssembler = { attributes: info.attributes, gpuVertexBuffers, gpuIndexBuffer, - gpuIndirectBuffer, glAttribs: [], glIndexType, diff --git a/native/cocos/core/assets/RenderingSubMesh.cpp b/native/cocos/core/assets/RenderingSubMesh.cpp index 363414194ca..8b06882b852 100644 --- a/native/cocos/core/assets/RenderingSubMesh.cpp +++ b/native/cocos/core/assets/RenderingSubMesh.cpp @@ -70,7 +70,6 @@ RenderingSubMesh::RenderingSubMesh(const gfx::BufferList &vertexBuffers, _iaInfo.attributes = attributes; _iaInfo.vertexBuffers = vertexBuffers; _iaInfo.indexBuffer = indexBuffer; - _iaInfo.indirectBuffer = indirectBuffer; } RenderingSubMesh::~RenderingSubMesh() { diff --git a/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp b/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp index 7689387fd31..19d51fd7e3d 100644 --- a/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp +++ b/native/cocos/renderer/gfx-agent/CommandBufferAgent.cpp @@ -361,6 +361,38 @@ void CommandBufferAgent::draw(const DrawInfo &info) { }); } +void CommandBufferAgent::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) +{ + auto *bufferAgent = static_cast(buffer); + + ENQUEUE_MESSAGE_5( + _messageQueue, CommandBufferDrawIndirect, + actor, getActor(), + buff, bufferAgent->getActor(), + offset, offset, + count, count, + stride, stride, + { + actor->drawIndirect(buff, offset, count, stride); + }); +} + +void CommandBufferAgent::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) +{ + auto *bufferAgent = static_cast(buffer); + + ENQUEUE_MESSAGE_5( + _messageQueue, CommandBufferDrawIndexedIndirect, + actor, getActor(), + buff, bufferAgent->getActor(), + offset, offset, + count, count, + stride, stride, + { + actor->drawIndexedIndirect(buff, offset, count, stride); + }); +} + void CommandBufferAgent::updateBuffer(Buffer *buff, const void *data, uint32_t size) { auto *bufferAgent = static_cast(buff); @@ -425,6 +457,27 @@ void CommandBufferAgent::copyTexture(Texture *srcTexture, Texture *dstTexture, c }); } +void CommandBufferAgent::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + Buffer *actorSrcBuffer = nullptr; + Buffer *actorDstBuffer = nullptr; + if (srcBuffer) actorSrcBuffer = static_cast(srcBuffer)->getActor(); + if (dstBuffer) actorDstBuffer = static_cast(dstBuffer)->getActor(); + + auto *actorRegions = _messageQueue->allocate(count); + memcpy(actorRegions, regions, count * sizeof(BufferCopy)); + + ENQUEUE_MESSAGE_5( + _messageQueue, CommandBufferCopyBuffer, + actor, getActor(), + srcBuffer, actorSrcBuffer, + dstBuffer, actorDstBuffer, + regions, actorRegions, + count, count, + { + actor->copyBuffer(srcBuffer, dstBuffer, regions, count); + }); +} + void CommandBufferAgent::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { Texture *actorSrcTexture = nullptr; Texture *actorDstTexture = nullptr; diff --git a/native/cocos/renderer/gfx-agent/CommandBufferAgent.h b/native/cocos/renderer/gfx-agent/CommandBufferAgent.h index b3cf37ff0e8..d555e4d232a 100644 --- a/native/cocos/renderer/gfx-agent/CommandBufferAgent.h +++ b/native/cocos/renderer/gfx-agent/CommandBufferAgent.h @@ -57,10 +57,13 @@ class CC_DLL CommandBufferAgent final : public Agent { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; diff --git a/native/cocos/renderer/gfx-agent/InputAssemblerAgent.cpp b/native/cocos/renderer/gfx-agent/InputAssemblerAgent.cpp index 1f7b9063aad..64b663c4888 100644 --- a/native/cocos/renderer/gfx-agent/InputAssemblerAgent.cpp +++ b/native/cocos/renderer/gfx-agent/InputAssemblerAgent.cpp @@ -54,9 +54,6 @@ void InputAssemblerAgent::doInit(const InputAssemblerInfo &info) { if (actorInfo.indexBuffer) { actorInfo.indexBuffer = static_cast(actorInfo.indexBuffer)->getActor(); } - if (actorInfo.indirectBuffer) { - actorInfo.indirectBuffer = static_cast(actorInfo.indirectBuffer)->getActor(); - } ENQUEUE_MESSAGE_2( DeviceAgent::getInstance()->getMessageQueue(), diff --git a/native/cocos/renderer/gfx-base/GFXCommandBuffer.h b/native/cocos/renderer/gfx-base/GFXCommandBuffer.h index 00a6d46e2aa..6225778fa9d 100644 --- a/native/cocos/renderer/gfx-base/GFXCommandBuffer.h +++ b/native/cocos/renderer/gfx-base/GFXCommandBuffer.h @@ -59,11 +59,14 @@ class CC_DLL CommandBuffer : public GFXObject, public RefCounted { virtual void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) = 0; virtual void nextSubpass() = 0; virtual void draw(const DrawInfo &info) = 0; + virtual void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) = 0; + virtual void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) = 0; virtual void updateBuffer(Buffer *buff, const void *data, uint32_t size) = 0; virtual void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) = 0; virtual void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) = 0; virtual void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0; virtual void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0; + virtual void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) = 0; virtual void execute(CommandBuffer *const *cmdBuffs, uint32_t count) = 0; virtual void dispatch(const DispatchInfo &info) = 0; virtual void beginQuery(QueryPool *queryPool, uint32_t id) = 0; diff --git a/native/cocos/renderer/gfx-base/GFXDef-common.h b/native/cocos/renderer/gfx-base/GFXDef-common.h index ab5c7bd810f..b865b7cc9b0 100644 --- a/native/cocos/renderer/gfx-base/GFXDef-common.h +++ b/native/cocos/renderer/gfx-base/GFXDef-common.h @@ -852,6 +852,7 @@ struct DeviceCaps { bool supportQuery{false}; bool supportVariableRateShading{false}; bool supportSubPassShading{false}; + bool supportMultiDrawIndirect{false}; float clipSpaceMinZ{-1.F}; float screenSpaceSignY{1.F}; @@ -909,6 +910,14 @@ struct TextureSubresRange { EXPOSE_COPY_FN(TextureSubresRange) }; +struct BufferCopy { + uint32_t srcOffset{0}; + uint32_t dstOffset{0}; + uint32_t size{0}; + + EXPOSE_COPY_FN(BufferCopy) +}; + struct TextureCopy { TextureSubresLayers srcSubres; Offset srcOffset; @@ -1029,6 +1038,21 @@ struct BufferViewInfo { EXPOSE_COPY_FN(BufferViewInfo) }; +struct DrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +}; + +struct DrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +}; + struct DrawInfo { uint32_t vertexCount{0}; uint32_t firstVertex{0}; @@ -1272,7 +1296,6 @@ struct InputAssemblerInfo { AttributeList attributes; BufferList vertexBuffers; Buffer *indexBuffer{nullptr}; // @ts-nullable - Buffer *indirectBuffer{nullptr}; // @ts-nullable EXPOSE_COPY_FN(InputAssemblerInfo) }; diff --git a/native/cocos/renderer/gfx-base/GFXDef.cpp b/native/cocos/renderer/gfx-base/GFXDef.cpp index 00a9bc6873e..822823c2e68 100644 --- a/native/cocos/renderer/gfx-base/GFXDef.cpp +++ b/native/cocos/renderer/gfx-base/GFXDef.cpp @@ -644,6 +644,19 @@ uint32_t formatSurfaceSize(Format format, uint32_t width, uint32_t height, uint3 return size; } +ccstd::hash_t computeAttributesHash(const AttributeList& attributes) { + ccstd::hash_t seed = static_cast(attributes.size()) * 6; + for (const auto &attribute : attributes) { + ccstd::hash_combine(seed, attribute.name); + ccstd::hash_combine(seed, attribute.format); + ccstd::hash_combine(seed, attribute.isNormalized); + ccstd::hash_combine(seed, attribute.stream); + ccstd::hash_combine(seed, attribute.isInstanced); + ccstd::hash_combine(seed, attribute.location); + } + return seed; +} + uint32_t gcd(uint32_t a, uint32_t b) { while (b) { uint32_t t = a % b; diff --git a/native/cocos/renderer/gfx-base/GFXDef.h b/native/cocos/renderer/gfx-base/GFXDef.h index 780ac44c065..9e0cf77ad8a 100644 --- a/native/cocos/renderer/gfx-base/GFXDef.h +++ b/native/cocos/renderer/gfx-base/GFXDef.h @@ -135,6 +135,8 @@ uint32_t formatSize(Format format, uint32_t width, uint32_t height, uint32_t dep uint32_t formatSurfaceSize(Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t mips); +ccstd::hash_t computeAttributesHash(const AttributeList &attributes); + /** * @en Get the memory size of the specified type. * @zh 得到 GFX 数据类型的大小。 diff --git a/native/cocos/renderer/gfx-base/GFXInputAssembler.cpp b/native/cocos/renderer/gfx-base/GFXInputAssembler.cpp index dc6a1da58fe..616b6851e7c 100644 --- a/native/cocos/renderer/gfx-base/GFXInputAssembler.cpp +++ b/native/cocos/renderer/gfx-base/GFXInputAssembler.cpp @@ -22,8 +22,7 @@ THE SOFTWARE. ****************************************************************************/ -#include "base/std/hash/hash.h" - +#include "GFXDef.h" #include "GFXBuffer.h" #include "GFXInputAssembler.h" #include "GFXObject.h" @@ -37,25 +36,11 @@ InputAssembler::InputAssembler() InputAssembler::~InputAssembler() = default; -ccstd::hash_t InputAssembler::computeAttributesHash() const { - ccstd::hash_t seed = static_cast(_attributes.size()) * 6; - for (const auto &attribute : _attributes) { - ccstd::hash_combine(seed, attribute.name); - ccstd::hash_combine(seed, attribute.format); - ccstd::hash_combine(seed, attribute.isNormalized); - ccstd::hash_combine(seed, attribute.stream); - ccstd::hash_combine(seed, attribute.isInstanced); - ccstd::hash_combine(seed, attribute.location); - } - return seed; -} - void InputAssembler::initialize(const InputAssemblerInfo &info) { _attributes = info.attributes; _vertexBuffers = info.vertexBuffers; _indexBuffer = info.indexBuffer; - _indirectBuffer = info.indirectBuffer; - _attributesHash = computeAttributesHash(); + _attributesHash = computeAttributesHash(_attributes); if (_indexBuffer) { _drawInfo.indexCount = _indexBuffer->getCount(); @@ -77,7 +62,6 @@ void InputAssembler::destroy() { _vertexBuffers.clear(); _indexBuffer = nullptr; - _indirectBuffer = nullptr; _drawInfo = DrawInfo(); } diff --git a/native/cocos/renderer/gfx-base/GFXInputAssembler.h b/native/cocos/renderer/gfx-base/GFXInputAssembler.h index 6d50248aa93..0400ab5e9b8 100644 --- a/native/cocos/renderer/gfx-base/GFXInputAssembler.h +++ b/native/cocos/renderer/gfx-base/GFXInputAssembler.h @@ -41,7 +41,6 @@ class CC_DLL InputAssembler : public GFXObject, public RefCounted { inline const AttributeList &getAttributes() const { return _attributes; } inline const BufferList &getVertexBuffers() const { return _vertexBuffers; } inline Buffer *getIndexBuffer() const { return _indexBuffer; } - inline Buffer *getIndirectBuffer() const { return _indirectBuffer; } inline ccstd::hash_t getAttributesHash() const { return _attributesHash; } inline const DrawInfo &getDrawInfo() const { return _drawInfo; } @@ -67,14 +66,11 @@ class CC_DLL InputAssembler : public GFXObject, public RefCounted { virtual void doInit(const InputAssemblerInfo &info) = 0; virtual void doDestroy() = 0; - ccstd::hash_t computeAttributesHash() const; - AttributeList _attributes; ccstd::hash_t _attributesHash = 0; BufferList _vertexBuffers; Buffer *_indexBuffer{nullptr}; - Buffer *_indirectBuffer{nullptr}; DrawInfo _drawInfo; }; diff --git a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp index 8c2e17a36b1..08f8bdb9489 100644 --- a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.cpp @@ -87,6 +87,12 @@ void EmptyCommandBuffer::nextSubpass() { void EmptyCommandBuffer::draw(const DrawInfo &info) { } +void EmptyCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { +} + +void EmptyCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { +} + void EmptyCommandBuffer::updateBuffer(Buffer *buff, const void *data, uint32_t size) { } @@ -102,6 +108,9 @@ void EmptyCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, c void EmptyCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) { } +void EmptyCommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { +} + void EmptyCommandBuffer::dispatch(const DispatchInfo &info) { } diff --git a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h index d429d23f61c..49853368838 100644 --- a/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h +++ b/native/cocos/renderer/gfx-empty/EmptyCommandBuffer.h @@ -48,11 +48,14 @@ class CC_DLL EmptyCommandBuffer final : public CommandBuffer { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-gles2/GLES2Buffer.cpp b/native/cocos/renderer/gfx-gles2/GLES2Buffer.cpp index 70e8834239a..111584c8b73 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Buffer.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Buffer.cpp @@ -48,10 +48,6 @@ void GLES2Buffer::doInit(const BufferInfo & /*info*/) { _gpuBuffer->stride = _stride; _gpuBuffer->count = _count; - if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - _gpuBuffer->indirects.resize(_count); - } - cmdFuncGLES2CreateBuffer(GLES2Device::getInstance(), _gpuBuffer); GLES2Device::getInstance()->getMemoryStatus().bufferSize += _size; CC_PROFILE_MEMORY_INC(Buffer, _size); diff --git a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp index daaf4efc6e9..85880ccead9 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp @@ -254,6 +254,22 @@ void GLES2CommandBuffer::setStencilCompareMask(StencilFace face, uint32_t ref, u if (hasFlag(face, StencilFace::BACK)) update(_curDynamicStates.stencilStatesBack); } +void GLES2CommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} + +void GLES2CommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} + void GLES2CommandBuffer::draw(const DrawInfo &info) { CC_PROFILE(GLES2CommandBufferDraw); if (_isStateInvalid) { @@ -320,6 +336,10 @@ void GLES2CommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture // should not copy texture in a secondary command buffer } +void GLES2CommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + // should not copy buffer in a secondary command buffer +} + void GLES2CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES2CmdBlitTexture *cmd = _cmdAllocator->blitTextureCmdPool.alloc(); if (srcTexture) cmd->gpuTextureSrc = static_cast(srcTexture)->gpuTexture(); diff --git a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h index 06185861895..12bc12d8b31 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h +++ b/native/cocos/renderer/gfx-gles2/GLES2CommandBuffer.h @@ -61,11 +61,14 @@ class CC_GLES2_API GLES2CommandBuffer : public CommandBuffer { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override {} void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override {} diff --git a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp index 1d9ca68f441..b1f685e0cd0 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2Commands.cpp @@ -554,7 +554,6 @@ void cmdFuncGLES2ResizeBuffer(GLES2Device *device, GLES2GPUBuffer *gpuBuffer) { device->stateCache()->glElementArrayBuffer = 0; } } else if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - gpuBuffer->indirects.resize(gpuBuffer->count); gpuBuffer->glTarget = GL_NONE; } else if ((hasFlag(gpuBuffer->usage, BufferUsageBit::UNIFORM)) || (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_DST)) || @@ -2596,51 +2595,24 @@ void cmdFuncGLES2Draw(GLES2Device *device, const DrawInfo &drawInfo) { GLenum glPrimitive = gfxStateCache.glPrimitive; if (gpuInputAssembler && gpuPipelineState) { - if (!gpuInputAssembler->gpuIndirectBuffer) { - if (gpuInputAssembler->gpuIndexBuffer) { - if (drawInfo.indexCount > 0) { - uint8_t *offset = nullptr; - offset += drawInfo.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; - if (drawInfo.instanceCount == 0) { - GL_CHECK(glDrawElements(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset)); - } else { - if (device->constantRegistry()->useDrawInstanced) { - GL_CHECK(glDrawElementsInstancedEXT(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset, drawInfo.instanceCount)); - } - } - } - } else if (drawInfo.vertexCount > 0) { + if (gpuInputAssembler->gpuIndexBuffer) { + if (drawInfo.indexCount > 0) { + uint8_t *offset = nullptr; + offset += drawInfo.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; if (drawInfo.instanceCount == 0) { - GL_CHECK(glDrawArrays(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount)); + GL_CHECK(glDrawElements(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset)); } else { if (device->constantRegistry()->useDrawInstanced) { - GL_CHECK(glDrawArraysInstancedEXT(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount)); + GL_CHECK(glDrawElementsInstancedEXT(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset, drawInfo.instanceCount)); } } } - } else { - for (size_t j = 0; j < gpuInputAssembler->gpuIndirectBuffer->indirects.size(); ++j) { - const DrawInfo &draw = gpuInputAssembler->gpuIndirectBuffer->indirects[j]; - if (gpuInputAssembler->gpuIndexBuffer) { - if (draw.indexCount > 0) { - uint8_t *offset = nullptr; - offset += draw.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; - if (drawInfo.instanceCount == 0) { - GL_CHECK(glDrawElements(glPrimitive, draw.indexCount, gpuInputAssembler->glIndexType, offset)); - } else { - if (device->constantRegistry()->useDrawInstanced) { - GL_CHECK(glDrawElementsInstancedEXT(glPrimitive, draw.indexCount, gpuInputAssembler->glIndexType, offset, draw.instanceCount)); - } - } - } - } else if (draw.vertexCount > 0) { - if (draw.instanceCount == 0) { - GL_CHECK(glDrawArrays(glPrimitive, draw.firstVertex, draw.vertexCount)); - } else { - if (device->constantRegistry()->useDrawInstanced) { - GL_CHECK(glDrawArraysInstancedEXT(glPrimitive, draw.firstVertex, draw.vertexCount, draw.instanceCount)); - } - } + } else if (drawInfo.vertexCount > 0) { + if (drawInfo.instanceCount == 0) { + GL_CHECK(glDrawArrays(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount)); + } else { + if (device->constantRegistry()->useDrawInstanced) { + GL_CHECK(glDrawArraysInstancedEXT(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount)); } } } @@ -2653,8 +2625,6 @@ void cmdFuncGLES2UpdateBuffer(GLES2Device *device, GLES2GPUBuffer *gpuBuffer, co if ((hasFlag(gpuBuffer->usage, BufferUsageBit::UNIFORM)) || (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_SRC))) { memcpy(gpuBuffer->buffer + offset, buffer, size); - } else if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - memcpy(reinterpret_cast(gpuBuffer->indirects.data()) + offset, buffer, size); } else { switch (gpuBuffer->glTarget) { case GL_ARRAY_BUFFER: { diff --git a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h index 99ce522f08d..b5b31eac436 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h +++ b/native/cocos/renderer/gfx-gles2/GLES2GPUObjects.h @@ -98,7 +98,6 @@ struct GLES2GPUBuffer { GLenum glTarget = 0; GLuint glBuffer = 0; uint8_t *buffer = nullptr; - DrawInfoList indirects; }; using GLES2GPUBufferList = ccstd::vector; @@ -251,7 +250,6 @@ struct GLES2GPUInputAssembler { AttributeList attributes; GLES2GPUBufferList gpuVertexBuffers; GLES2GPUBuffer *gpuIndexBuffer = nullptr; - GLES2GPUBuffer *gpuIndirectBuffer = nullptr; GLES2GPUAttributeList glAttribs; GLenum glIndexType = 0; ccstd::unordered_map glVAOs; diff --git a/native/cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp b/native/cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp index 1599cf842c5..ca6567f1431 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp @@ -52,10 +52,6 @@ void GLES2InputAssembler::doInit(const InputAssemblerInfo &info) { _gpuInputAssembler->gpuIndexBuffer = static_cast(info.indexBuffer)->gpuBuffer(); } - if (info.indirectBuffer) { - _gpuInputAssembler->gpuIndirectBuffer = static_cast(info.indirectBuffer)->gpuBuffer(); - } - cmdFuncGLES2CreateInputAssembler(GLES2Device::getInstance(), _gpuInputAssembler); } diff --git a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp index 1c3832849a8..973fb81b031 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp @@ -80,6 +80,22 @@ void GLES2PrimaryCommandBuffer::nextSubpass() { cmdFuncGLES2BeginRenderPass(GLES2Device::getInstance(), ++_curSubpassIdx); } +void GLES2PrimaryCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} + +void GLES2PrimaryCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} + void GLES2PrimaryCommandBuffer::draw(const DrawInfo &info) { CC_PROFILE(GLES2PrimaryCommandBufferDraw); if (_isStateInvalid) { @@ -175,6 +191,9 @@ void GLES2PrimaryCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTex cmdFuncGLES2BlitTexture(GLES2Device::getInstance(), gpuTextureSrc, gpuTextureDst, blitRegions.data(), count, Filter::POINT); } +void GLES2PrimaryCommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { +} + void GLES2PrimaryCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES2GPUTexture *gpuTextureSrc = nullptr; GLES2GPUTexture *gpuTextureDst = nullptr; diff --git a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h index 2a3411c9eef..299c0e362c3 100644 --- a/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h +++ b/native/cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h @@ -40,6 +40,8 @@ class CC_GLES2_API GLES2PrimaryCommandBuffer final : public GLES2CommandBuffer { void endRenderPass() override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void setViewport(const Viewport &vp) override; void setScissor(const Rect &rect) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; @@ -47,6 +49,7 @@ class CC_GLES2_API GLES2PrimaryCommandBuffer final : public GLES2CommandBuffer { void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; protected: diff --git a/native/cocos/renderer/gfx-gles3/GLES3Buffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3Buffer.cpp index dfaa7b8f496..f8d6a86b38e 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Buffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Buffer.cpp @@ -48,10 +48,6 @@ void GLES3Buffer::doInit(const BufferInfo & /*info*/) { _gpuBuffer->stride = _stride; _gpuBuffer->count = _count; - if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - _gpuBuffer->indirects.resize(_count); - } - cmdFuncGLES3CreateBuffer(GLES3Device::getInstance(), _gpuBuffer); GLES3Device::getInstance()->getMemoryStatus().bufferSize += _size; CC_PROFILE_MEMORY_INC(Buffer, _size); @@ -68,8 +64,6 @@ void GLES3Buffer::doInit(const BufferViewInfo &info) { _gpuBuffer->glTarget = buffer->_gpuBuffer->glTarget; _gpuBuffer->glBuffer = buffer->_gpuBuffer->glBuffer; _gpuBuffer->glOffset = info.offset; - _gpuBuffer->buffer = buffer->_gpuBuffer->buffer; - _gpuBuffer->indirects = buffer->_gpuBuffer->indirects; } void GLES3Buffer::doDestroy() { diff --git a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp index 706dd795a59..182b76ae343 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp @@ -255,6 +255,20 @@ void GLES3CommandBuffer::setStencilCompareMask(StencilFace face, uint32_t ref, u if (hasFlag(face, StencilFace::BACK)) update(_curDynamicStates.stencilStatesBack); } +void GLES3CommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} +void GLES3CommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + // not support + std::ignore = buffer; + std::ignore = offset; + std::ignore = count; + std::ignore = stride; +} void GLES3CommandBuffer::draw(const DrawInfo &info) { CC_PROFILE(GLES3CommandBufferDraw); if (_isStateInvalid) { @@ -307,6 +321,10 @@ void GLES3CommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture // should not resolve texture in a secondary command buffer } +void GLES3CommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + // should not copy buffer in a secondary command buffer +} + void GLES3CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES3CmdBlitTexture *cmd = _cmdAllocator->blitTextureCmdPool.alloc(); if (srcTexture) cmd->gpuTextureSrc = static_cast(srcTexture)->gpuTexture(); diff --git a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h index d42b50d43bc..2f08d4accee 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h +++ b/native/cocos/renderer/gfx-gles3/GLES3CommandBuffer.h @@ -60,11 +60,14 @@ class CC_GLES3_API GLES3CommandBuffer : public CommandBuffer { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const * /*buffers*/, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const * /*textures*/, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index afddfc2d1a7..d08f3e60768 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -658,11 +658,15 @@ void cmdFuncGLES3CreateBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer) { device->stateCache()->glShaderStorageBuffer = 0; } } else if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - gpuBuffer->glTarget = GL_NONE; - } else if ((hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_DST)) || - (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_SRC))) { - gpuBuffer->buffer = static_cast(CC_MALLOC(gpuBuffer->size)); - gpuBuffer->glTarget = GL_NONE; + gpuBuffer->glTarget = GL_DRAW_INDIRECT_BUFFER; + GL_CHECK(glGenBuffers(1, &gpuBuffer->glBuffer)); + if (device->stateCache()->glDrawIndirectBuffer != gpuBuffer->glBuffer) { + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->glBuffer)); + } + + GL_CHECK(glBufferData(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->size, nullptr, glUsage)); + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0)); + device->stateCache()->glDrawIndirectBuffer = 0; } else { CC_ABORT(); gpuBuffer->glTarget = GL_NONE; @@ -786,8 +790,16 @@ void cmdFuncGLES3ResizeBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer) { device->stateCache()->glUniformBuffer = 0; } } else if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - gpuBuffer->indirects.resize(gpuBuffer->count); - gpuBuffer->glTarget = GL_NONE; + gpuBuffer->glTarget = GL_DRAW_INDIRECT_BUFFER; + if (gpuBuffer->size) { + if (device->stateCache()->glDrawIndirectBuffer != gpuBuffer->glBuffer) { + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->glBuffer)); + } + + GL_CHECK(glBufferData(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->size, nullptr, glUsage)); + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0)); + device->stateCache()->glDrawIndirectBuffer = 0; + } } else if ((hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_DST)) || (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_SRC))) { if (gpuBuffer->buffer) { @@ -2468,6 +2480,41 @@ void cmdFuncGLES3BindState(GLES3Device *device, GLES3GPUPipelineState *gpuPipeli } } +void cmdFuncGLES3DrawIndirect(GLES3Device *device, + GLES3GPUBuffer *gpuBuffer, + uint32_t offset, + uint32_t count, + uint32_t stride, + bool indexed) { + uint32_t bufferOffset = gpuBuffer->glOffset + offset; + GLES3GPUStateCache *cache = device->stateCache(); + GLenum primitive = cache->gfxStateCache.glPrimitive; + + if (cache->glDrawIndirectBuffer != gpuBuffer->glBuffer) { + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->glBuffer)); + cache->glDrawIndirectBuffer = gpuBuffer->glBuffer; + } + + uint8_t *ptr = nullptr; + if (device->constantRegistry()->multiDrawIndirect) { + if (indexed) { + GL_CHECK(glMultiDrawElementsIndirectEXT(primitive, cache->gfxStateCache.gpuInputAssembler->glIndexType, + ptr + bufferOffset, count, stride)); + } else { + GL_CHECK(glMultiDrawArraysIndirectEXT(primitive, ptr + bufferOffset, count, stride)); + } + } else { + for (uint32_t i = 0U; i < count; ++i) { + uint32_t currentOffset = bufferOffset + i * stride; + if (indexed) { + GL_CHECK(glDrawElementsIndirect(primitive, cache->gfxStateCache.gpuInputAssembler->glIndexType, ptr + currentOffset)); + } else { + GL_CHECK(glDrawArraysIndirect(primitive, ptr + currentOffset)); + } + } + } +} + void cmdFuncGLES3Draw(GLES3Device *device, const DrawInfo &drawInfo) { GLES3ObjectCache &gfxStateCache = device->stateCache()->gfxStateCache; GLES3GPUPipelineState *gpuPipelineState = gfxStateCache.gpuPipelineState; @@ -2475,44 +2522,21 @@ void cmdFuncGLES3Draw(GLES3Device *device, const DrawInfo &drawInfo) { GLenum glPrimitive = gfxStateCache.glPrimitive; if (gpuInputAssembler && gpuPipelineState) { - if (!gpuInputAssembler->gpuIndirectBuffer) { - if (gpuInputAssembler->gpuIndexBuffer) { - if (drawInfo.indexCount > 0) { - uint8_t *offset = nullptr; - offset += drawInfo.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; - if (drawInfo.instanceCount == 0) { - GL_CHECK(glDrawElements(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset)); - } else { - GL_CHECK(glDrawElementsInstanced(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset, drawInfo.instanceCount)); - } - } - } else if (drawInfo.vertexCount > 0) { + if (gpuInputAssembler->gpuIndexBuffer) { + if (drawInfo.indexCount > 0) { + uint8_t *offset = nullptr; + offset += drawInfo.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; if (drawInfo.instanceCount == 0) { - GL_CHECK(glDrawArrays(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount)); + GL_CHECK(glDrawElements(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset)); } else { - GL_CHECK(glDrawArraysInstanced(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount)); + GL_CHECK(glDrawElementsInstanced(glPrimitive, drawInfo.indexCount, gpuInputAssembler->glIndexType, offset, drawInfo.instanceCount)); } } - } else { - for (size_t j = 0; j < gpuInputAssembler->gpuIndirectBuffer->indirects.size(); ++j) { - const DrawInfo &draw = gpuInputAssembler->gpuIndirectBuffer->indirects[j]; - if (gpuInputAssembler->gpuIndexBuffer) { - if (draw.indexCount > 0) { - uint8_t *offset = nullptr; - offset += draw.firstIndex * gpuInputAssembler->gpuIndexBuffer->stride; - if (draw.instanceCount == 0) { - GL_CHECK(glDrawElements(glPrimitive, draw.indexCount, gpuInputAssembler->glIndexType, offset)); - } else { - GL_CHECK(glDrawElementsInstanced(glPrimitive, draw.indexCount, gpuInputAssembler->glIndexType, offset, draw.instanceCount)); - } - } - } else if (draw.vertexCount > 0) { - if (draw.instanceCount == 0) { - GL_CHECK(glDrawArrays(glPrimitive, draw.firstVertex, draw.vertexCount)); - } else { - GL_CHECK(glDrawArraysInstanced(glPrimitive, draw.firstVertex, draw.vertexCount, draw.instanceCount)); - } - } + } else if (drawInfo.vertexCount > 0) { + if (drawInfo.instanceCount == 0) { + GL_CHECK(glDrawArrays(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount)); + } else { + GL_CHECK(glDrawArraysInstanced(glPrimitive, drawInfo.firstVertex, drawInfo.vertexCount, drawInfo.instanceCount)); } } } @@ -2553,9 +2577,7 @@ static void uploadBufferData(GLenum target, GLintptr offset, GLsizeiptr length, void cmdFuncGLES3UpdateBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer, const void *buffer, uint32_t offset, uint32_t size) { GLES3ObjectCache &gfxStateCache = device->stateCache()->gfxStateCache; - if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - memcpy(reinterpret_cast(gpuBuffer->indirects.data()) + offset, buffer, size); - } else if (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_SRC) && gpuBuffer->buffer != nullptr) { + if (hasFlag(gpuBuffer->usage, BufferUsageBit::TRANSFER_SRC) && gpuBuffer->buffer != nullptr) { memcpy(gpuBuffer->buffer + offset, buffer, size); } else { switch (gpuBuffer->glTarget) { @@ -2601,6 +2623,14 @@ void cmdFuncGLES3UpdateBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer, co uploadBufferData(GL_SHADER_STORAGE_BUFFER, offset, size, buffer); break; } + case GL_DRAW_INDIRECT_BUFFER: { + if (device->stateCache()->glDrawIndirectBuffer != gpuBuffer->glBuffer) { + GL_CHECK(glBindBuffer(GL_DRAW_INDIRECT_BUFFER, gpuBuffer->glBuffer)); + device->stateCache()->glDrawIndirectBuffer = gpuBuffer->glBuffer; + } + uploadBufferData(GL_DRAW_INDIRECT_BUFFER, offset, size, buffer); + break; + } default: CC_ABORT(); break; @@ -2924,6 +2954,21 @@ void cmdFuncGLES3BlitTexture(GLES3Device *device, GLES3GPUTexture *gpuTextureSrc } } +void cmdFuncGLES3CopyBuffer(GLES3GPUBuffer *gpuBufferSrc,GLES3GPUBuffer *gpuBufferDst, + const BufferCopy *regions, uint32_t count) { + GL_CHECK(glBindBuffer(GL_COPY_READ_BUFFER, gpuBufferSrc->glBuffer)); + GL_CHECK(glBindBuffer(GL_COPY_WRITE_BUFFER, gpuBufferDst->glBuffer)); + + for (uint32_t i = 0; i < count; ++i) { + const auto © = regions[i]; + GL_CHECK(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + copy.srcOffset, copy.dstOffset, copy.size)); + } + + GL_CHECK(glBindBuffer(GL_COPY_READ_BUFFER, 0)); + GL_CHECK(glBindBuffer(GL_COPY_WRITE_BUFFER, 0)); +} + void cmdFuncGLES3ExecuteCmds(GLES3Device *device, GLES3CmdPackage *cmdPackage) { if (!cmdPackage->cmds.size()) return; diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.h b/native/cocos/renderer/gfx-gles3/GLES3Commands.h index c9d612550de..e8e1f6a8725 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.h +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.h @@ -281,6 +281,12 @@ void cmdFuncGLES3BindState(GLES3Device *device, const DynamicStates *dynamicStates = nullptr); void cmdFuncGLES3Draw(GLES3Device *device, const DrawInfo &drawInfo); +void cmdFuncGLES3DrawIndirect(GLES3Device *device, + GLES3GPUBuffer *gpuBuffer, + uint32_t offset, + uint32_t count, + uint32_t stride, + bool indexed); void cmdFuncGLES3UpdateBuffer(GLES3Device *device, GLES3GPUBuffer *gpuBuffer, @@ -306,6 +312,11 @@ void cmdFuncGLES3BlitTexture(GLES3Device *device, uint32_t count, Filter filter); +void cmdFuncGLES3CopyBuffer(GLES3GPUBuffer *gpuBufferSrc, + GLES3GPUBuffer *gpuBufferDst, + const BufferCopy *regions, + uint32_t count); + void cmdFuncGLES3ExecuteCmds(GLES3Device *device, GLES3CmdPackage *cmdPackage); void cmdFuncGLES3Dispatch(GLES3Device *device, const GLES3GPUDispatchInfo &info); diff --git a/native/cocos/renderer/gfx-gles3/GLES3Device.cpp b/native/cocos/renderer/gfx-gles3/GLES3Device.cpp index 79bc6937af8..c5e1bdfc4af 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Device.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Device.cpp @@ -152,6 +152,7 @@ bool GLES3Device::doInit(const DeviceInfo & /*info*/) { _features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = true; fbfLevelStr += "_DEPTH_STENCIL"; } + _gpuConstantRegistry->multiDrawIndirect = checkExtension((CC_TOSTR(multi_draw_indirect))); ccstd::string msaaLevelStr = "NONE"; #if CC_PLATFORM != CC_PLATFORM_WINDOWS || ALLOW_MULTISAMPLED_RENDER_TO_TEXTURE_ON_DESKTOP diff --git a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h index 169767fe082..7aeebdb6e7b 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h +++ b/native/cocos/renderer/gfx-gles3/GLES3GPUObjects.h @@ -43,6 +43,7 @@ struct GLES3GPUConstantRegistry { MSRTSupportLevel mMSRT{MSRTSupportLevel::NONE}; FBFSupportLevel mFBF{FBFSupportLevel::NONE}; + uint32_t multiDrawIndirect = false; }; class GLES3GPUStateCache; @@ -116,7 +117,6 @@ struct GLES3GPUBuffer { GLuint glBuffer = 0; GLuint glOffset = 0; uint8_t *buffer = nullptr; - DrawInfoList indirects; }; using GLES3GPUBufferList = ccstd::vector; @@ -307,7 +307,6 @@ struct GLES3GPUInputAssembler { AttributeList attributes; GLES3GPUBufferList gpuVertexBuffers; GLES3GPUBuffer *gpuIndexBuffer = nullptr; - GLES3GPUBuffer *gpuIndirectBuffer = nullptr; GLES3GPUAttributeList glAttribs; GLenum glIndexType = 0; ccstd::unordered_map glVAOs; @@ -460,6 +459,7 @@ class GLES3GPUStateCache final { ccstd::vector glBindSSBOs; ccstd::vector glBindSSBOOffsets; GLuint glDispatchIndirectBuffer = 0; + GLuint glDrawIndirectBuffer = 0; GLuint glVAO = 0; uint32_t texUint = 0; ccstd::vector glTextures; @@ -506,6 +506,7 @@ class GLES3GPUStateCache final { glBindSSBOs.assign(glBindSSBOs.size(), 0U); glBindSSBOOffsets.assign(glBindSSBOOffsets.size(), 0U); glDispatchIndirectBuffer = 0; + glDrawIndirectBuffer = 0; glVAO = 0; texUint = 0; glTextures.assign(glTextures.size(), 0U); diff --git a/native/cocos/renderer/gfx-gles3/GLES3InputAssembler.cpp b/native/cocos/renderer/gfx-gles3/GLES3InputAssembler.cpp index c988df02020..bdd55424055 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3InputAssembler.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3InputAssembler.cpp @@ -52,10 +52,6 @@ void GLES3InputAssembler::doInit(const InputAssemblerInfo &info) { _gpuInputAssembler->gpuIndexBuffer = static_cast(info.indexBuffer)->gpuBuffer(); } - if (info.indirectBuffer) { - _gpuInputAssembler->gpuIndirectBuffer = static_cast(info.indirectBuffer)->gpuBuffer(); - } - cmdFuncGLES3CreateInputAssembler(GLES3Device::getInstance(), _gpuInputAssembler); } diff --git a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp index c409f6023a8..4b9c5e4cabd 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.cpp @@ -80,6 +80,26 @@ void GLES3PrimaryCommandBuffer::nextSubpass() { ++_curSubpassIdx; } +void GLES3PrimaryCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + if (_isStateInvalid) { + bindStates(); + } + + auto *glesBuffer = static_cast(buffer); + auto *gpuBuffer = glesBuffer->gpuBuffer(); + cmdFuncGLES3DrawIndirect(GLES3Device::getInstance(), gpuBuffer, offset, count, stride, false); +} + +void GLES3PrimaryCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + if (_isStateInvalid) { + bindStates(); + } + + auto *glesBuffer = static_cast(buffer); + auto *gpuBuffer = glesBuffer->gpuBuffer(); + cmdFuncGLES3DrawIndirect(GLES3Device::getInstance(), gpuBuffer, offset, count, stride, true); +} + void GLES3PrimaryCommandBuffer::draw(const DrawInfo &info) { CC_PROFILE(GLES3PrimaryCommandBufferDraw); if (_isStateInvalid) { @@ -165,6 +185,13 @@ void GLES3PrimaryCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTex cmdFuncGLES3BlitTexture(GLES3Device::getInstance(), gpuTextureSrc, gpuTextureDst, blitRegions.data(), count, Filter::POINT); } +void GLES3PrimaryCommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + GLES3GPUBuffer *srcGLBuffer = static_cast(srcBuffer)->gpuBuffer(); + GLES3GPUBuffer *dstGLBuffer = static_cast(dstBuffer)->gpuBuffer(); + + cmdFuncGLES3CopyBuffer(srcGLBuffer, dstGLBuffer, regions, count); +} + void GLES3PrimaryCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { GLES3GPUTexture *gpuTextureSrc = nullptr; GLES3GPUTexture *gpuTextureDst = nullptr; diff --git a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h index 3ae09735302..5f2de6a58cd 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h +++ b/native/cocos/renderer/gfx-gles3/GLES3PrimaryCommandBuffer.h @@ -40,6 +40,8 @@ class CC_GLES3_API GLES3PrimaryCommandBuffer final : public GLES3CommandBuffer { void endRenderPass() override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void setViewport(const Viewport &vp) override; void setScissor(const Rect &rect) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; @@ -50,6 +52,7 @@ class CC_GLES3_API GLES3PrimaryCommandBuffer final : public GLES3CommandBuffer { void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void beginQuery(QueryPool *queryPool, uint32_t id) override; void endQuery(QueryPool *queryPool, uint32_t id) override; void resetQueryPool(QueryPool *queryPool) override; diff --git a/native/cocos/renderer/gfx-metal/MTLBuffer.h b/native/cocos/renderer/gfx-metal/MTLBuffer.h index b214bedfc82..440eef050b4 100644 --- a/native/cocos/renderer/gfx-metal/MTLBuffer.h +++ b/native/cocos/renderer/gfx-metal/MTLBuffer.h @@ -54,8 +54,6 @@ class CCMTLBuffer final : public Buffer { inline CCMTLGPUBuffer *gpuBuffer() { return _gpuBuffer; } inline MTLIndexType getIndexType() const { return _indexType; } - inline bool isDrawIndirectByIndex() const { return _isDrawIndirectByIndex; } - inline const DrawInfoList &getDrawInfos() const { return _drawInfos; } protected: void doInit(const BufferInfo &info) override; @@ -72,11 +70,6 @@ class CCMTLBuffer final : public Buffer { uint32_t _bufferViewOffset = 0; uint8_t _lastUpdateCycle{0}; - bool _isDrawIndirectByIndex = false; - ccstd::vector _indexedPrimitivesIndirectArguments; - ccstd::vector _primitiveIndirectArguments; - DrawInfoList _drawInfos; - CCMTLGPUBuffer *_gpuBuffer = nullptr; }; diff --git a/native/cocos/renderer/gfx-metal/MTLBuffer.mm b/native/cocos/renderer/gfx-metal/MTLBuffer.mm index 9d36132a92e..1b1ec586fa1 100644 --- a/native/cocos/renderer/gfx-metal/MTLBuffer.mm +++ b/native/cocos/renderer/gfx-metal/MTLBuffer.mm @@ -69,16 +69,9 @@ of this software and associated engine source code (the "Software"), a limited, if (hasFlag(_usage, BufferUsageBit::VERTEX) || hasFlag(_usage, BufferUsageBit::UNIFORM) || hasFlag(_usage, BufferUsageBit::INDEX) || - hasFlag(_usage, BufferUsageBit::STORAGE)) { + hasFlag(_usage, BufferUsageBit::STORAGE) || + hasFlag(_usage, BufferUsageBit::INDIRECT)) { createMTLBuffer(_size, _memUsage); - } else if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - if (_isIndirectDrawSupported) { - createMTLBuffer(_size, _memUsage); - _primitiveIndirectArguments.resize(_count); - _indexedPrimitivesIndirectArguments.resize(_count); - } else { - _drawInfos.resize(_count); - } } CCMTLDevice::getInstance()->getMemoryStatus().bufferSize += _size; CC_PROFILE_MEMORY_INC(Buffer, _size); @@ -90,10 +83,6 @@ of this software and associated engine source code (the "Software"), a limited, _indexType = ccBuffer->getIndexType(); _mtlResourceOptions = ccBuffer->_mtlResourceOptions; _isIndirectDrawSupported = ccBuffer->_isIndirectDrawSupported; - _isDrawIndirectByIndex = ccBuffer->_isDrawIndirectByIndex; - _indexedPrimitivesIndirectArguments = ccBuffer->_indexedPrimitivesIndirectArguments; - _primitiveIndirectArguments = ccBuffer->_primitiveIndirectArguments; - _drawInfos = ccBuffer->_drawInfos; _bufferViewOffset = info.offset; _isBufferView = true; } @@ -143,18 +132,6 @@ of this software and associated engine source code (the "Software"), a limited, CCMTLDevice::getInstance()->getMemoryStatus().bufferSize -= _size; CC_PROFILE_MEMORY_DEC(Buffer, _size); - if (!_indexedPrimitivesIndirectArguments.empty()) { - _indexedPrimitivesIndirectArguments.clear(); - } - - if (!_primitiveIndirectArguments.empty()) { - _primitiveIndirectArguments.clear(); - } - - if (!_drawInfos.empty()) { - _drawInfos.clear(); - } - if (_gpuBuffer) { id mtlBuffer = _gpuBuffer->mtlBuffer; _gpuBuffer->mtlBuffer = nil; @@ -176,7 +153,8 @@ of this software and associated engine source code (the "Software"), a limited, void CCMTLBuffer::doResize(uint32_t size, uint32_t count) { if (hasFlag(_usage, BufferUsageBit::VERTEX) || hasFlag(_usage, BufferUsageBit::INDEX) || - hasFlag(_usage, BufferUsageBit::UNIFORM)) { + hasFlag(_usage, BufferUsageBit::UNIFORM) || + hasFlag(_usage, BufferUsageBit::INDIRECT)) { createMTLBuffer(size, _memUsage); } @@ -187,15 +165,6 @@ of this software and associated engine source code (the "Software"), a limited, _size = size; _count = count; - if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - if (_isIndirectDrawSupported) { - createMTLBuffer(size, _memUsage); - _primitiveIndirectArguments.resize(_count); - _indexedPrimitivesIndirectArguments.resize(_count); - } else { - _drawInfos.resize(_count); - } - } } void CCMTLBuffer::update(const void *buffer, uint32_t size) { @@ -205,52 +174,7 @@ of this software and associated engine source code (the "Software"), a limited, return; } - _isDrawIndirectByIndex = false; - - if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - uint32_t drawInfoCount = size / _stride; - const auto *drawInfo = static_cast(buffer); - if (drawInfoCount > 0) { - if (drawInfo->indexCount) { - _isDrawIndirectByIndex = true; - } - } - - if (_isIndirectDrawSupported) { - if (drawInfoCount > 0) { - if (_isDrawIndirectByIndex) { - uint32_t stride = sizeof(MTLDrawIndexedPrimitivesIndirectArguments); - - for (uint32_t i = 0; i < drawInfoCount; ++i) { - auto &arguments = _indexedPrimitivesIndirectArguments[i]; - arguments.indexCount = drawInfo->indexCount; - arguments.instanceCount = std::max(drawInfo->instanceCount, 1U); - arguments.indexStart = drawInfo->firstIndex; - arguments.baseVertex = drawInfo->firstVertex; - arguments.baseInstance = drawInfo->firstInstance; - ++drawInfo; - } - updateMTLBuffer(_indexedPrimitivesIndirectArguments.data(), 0, drawInfoCount * stride); - } else { - uint32_t stride = sizeof(MTLDrawPrimitivesIndirectArguments); - - for (uint32_t i = 0; i < drawInfoCount; ++i) { - auto &arguments = _primitiveIndirectArguments[i]; - arguments.vertexCount = drawInfo->vertexCount; - arguments.instanceCount = std::max(drawInfo->instanceCount, 1U); - arguments.vertexStart = drawInfo->firstVertex; - arguments.baseInstance = drawInfo->firstInstance; - ++drawInfo; - } - updateMTLBuffer(_primitiveIndirectArguments.data(), 0, drawInfoCount * stride); - } - } - } else { - memcpy(_drawInfos.data(), buffer, size); - } - } else { - updateMTLBuffer(buffer, 0, size); - } + updateMTLBuffer(buffer, 0, size); } void CCMTLBuffer::updateMTLBuffer(const void *buffer, uint32_t /*offset*/, uint32_t size) { diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h index bb38f1530cd..207e1ec74d7 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.h @@ -69,11 +69,14 @@ class CCMTLCommandBuffer final : public CommandBuffer { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; @@ -96,6 +99,7 @@ class CCMTLCommandBuffer final : public CommandBuffer { void doInit(const CommandBufferInfo &info) override; void doDestroy() override; + void prepareForDraw(); void bindDescriptorSets(); void updateDepthStencilState(uint32_t subPassIndex, MTLRenderPassDescriptor *descriptor); static bool isRenderingEntireDrawable(const Rect &rect, const CCMTLFramebuffer *renderPass); diff --git a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm index 84cd6f958e0..484de3d365b 100644 --- a/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm +++ b/native/cocos/renderer/gfx-metal/MTLCommandBuffer.mm @@ -564,120 +564,96 @@ of this software and associated engine source code (the "Software"), a limited, } } -void CCMTLCommandBuffer::draw(const DrawInfo &info) { +void CCMTLCommandBuffer::prepareForDraw() { if(!_gpuCommandBufferObj->pipelineState || - !_gpuCommandBufferObj->pipelineState->getGPUPipelineState() || - !_gpuCommandBufferObj->pipelineState->getGPUPipelineState()->mtlRenderPipelineState) { + !_gpuCommandBufferObj->pipelineState->getGPUPipelineState() || + !_gpuCommandBufferObj->pipelineState->getGPUPipelineState()->mtlRenderPipelineState) { return; } - CC_PROFILE(CCMTLCommandBufferDraw); if (_firstDirtyDescriptorSet < _GPUDescriptorSets.size()) { bindDescriptorSets(); } +} + +void CCMTLCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + prepareForDraw(); + auto mtlEncoder = _renderEncoder.getMTLEncoder(); + auto *mtlBuffer = static_cast(buffer); + for (uint32_t i = 0; i < count; ++i) { + const auto off = mtlBuffer->currentOffset() + offset + i * stride; + [mtlEncoder drawPrimitives: _mtlPrimitiveType + indirectBuffer: mtlBuffer->mtlBuffer() + indirectBufferOffset: off]; + } +} + +void CCMTLCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + prepareForDraw(); + CCMTLInputAssembler *inputAssembler = _gpuCommandBufferObj->inputAssembler; + const auto *indexBuffer = static_cast(inputAssembler->getIndexBuffer()); + + auto mtlEncoder = _renderEncoder.getMTLEncoder(); + auto *mtlBuffer = static_cast(buffer); + for (uint32_t i = 0; i < count; ++i) { + const auto off = mtlBuffer->currentOffset() + offset + i * stride; + [mtlEncoder drawIndexedPrimitives: _mtlPrimitiveType + indexType: indexBuffer->getIndexType() + indexBuffer: indexBuffer->mtlBuffer() + indexBufferOffset: indexBuffer->currentOffset() + indirectBuffer: mtlBuffer->mtlBuffer() + indirectBufferOffset: off]; + } +} + +void CCMTLCommandBuffer::draw(const DrawInfo &info) { + CC_PROFILE(CCMTLCommandBufferDraw); + prepareForDraw(); CCMTLInputAssembler *inputAssembler = _gpuCommandBufferObj->inputAssembler; - const auto *indirectBuffer = static_cast(inputAssembler->getIndirectBuffer()); const auto *indexBuffer = static_cast(inputAssembler->getIndexBuffer()); auto mtlEncoder = _renderEncoder.getMTLEncoder(); - if (indirectBuffer) { - if (_indirectDrawSuppotred) { - ++_numDrawCalls; - if (indirectBuffer->isDrawIndirectByIndex()) { - [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType - indexType:indexBuffer->getIndexType() - indexBuffer:indexBuffer->mtlBuffer() - indexBufferOffset:indexBuffer->currentOffset() - indirectBuffer:indirectBuffer->mtlBuffer() - indirectBufferOffset:indirectBuffer->currentOffset()]; - } else { - [mtlEncoder drawPrimitives:_mtlPrimitiveType - indirectBuffer:indirectBuffer->mtlBuffer() - indirectBufferOffset:indirectBuffer->currentOffset()]; - } + if (info.indexCount > 0) { + uint32_t offset = 0; + offset += info.firstIndex * indexBuffer->getStride(); + if (info.instanceCount == 0) { + [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType + indexCount:info.indexCount + indexType:indexBuffer->getIndexType() + indexBuffer:indexBuffer->mtlBuffer() + indexBufferOffset:offset + indexBuffer->currentOffset()]; } else { - uint32_t stride = indirectBuffer->getStride(); - uint32_t offset = 0; - uint32_t drawInfoCount = indirectBuffer->getCount(); - const auto &drawInfos = indirectBuffer->getDrawInfos(); - _numDrawCalls += drawInfoCount; - - for (uint32_t i = 0; i < drawInfoCount; ++i) { - const auto &drawInfo = drawInfos[i]; - offset += drawInfo.firstIndex * stride; - if (indirectBuffer->isDrawIndirectByIndex()) { - if (drawInfo.instanceCount == 0) { - // indexbuffer offset: [backbuffer(triplebuffer maybe) offset] + [offset in this drawcall] - [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType - indexCount:drawInfo.indexCount - indexType:indexBuffer->getIndexType() - indexBuffer:indexBuffer->mtlBuffer() - indexBufferOffset:offset + indexBuffer->currentOffset()]; - } else { - [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType - indexCount:drawInfo.indexCount - indexType:indexBuffer->getIndexType() - indexBuffer:indexBuffer->mtlBuffer() - indexBufferOffset:offset + indexBuffer->currentOffset() - instanceCount:drawInfo.instanceCount]; - } - } else { - if (drawInfo.instanceCount == 0) { - [mtlEncoder drawPrimitives:_mtlPrimitiveType - vertexStart:drawInfo.firstVertex - vertexCount:drawInfo.vertexCount]; - } else { - [mtlEncoder drawPrimitives:_mtlPrimitiveType - vertexStart:drawInfo.firstVertex - vertexCount:drawInfo.vertexCount - instanceCount:drawInfo.instanceCount]; - } - } - } + [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType + indexCount:info.indexCount + indexType:indexBuffer->getIndexType() + indexBuffer:indexBuffer->mtlBuffer() + indexBufferOffset:offset + indexBuffer->currentOffset() + instanceCount:info.instanceCount]; } - } else { - if (info.indexCount > 0) { - uint32_t offset = 0; - offset += info.firstIndex * indexBuffer->getStride(); - if (info.instanceCount == 0) { - [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType - indexCount:info.indexCount - indexType:indexBuffer->getIndexType() - indexBuffer:indexBuffer->mtlBuffer() - indexBufferOffset:offset + indexBuffer->currentOffset()]; - } else { - [mtlEncoder drawIndexedPrimitives:_mtlPrimitiveType - indexCount:info.indexCount - indexType:indexBuffer->getIndexType() - indexBuffer:indexBuffer->mtlBuffer() - indexBufferOffset:offset + indexBuffer->currentOffset() - instanceCount:info.instanceCount]; - } - } else if (info.vertexCount) { - if (info.instanceCount == 0) { - [mtlEncoder drawPrimitives:_mtlPrimitiveType - vertexStart:info.firstVertex - vertexCount:info.vertexCount]; - } else { - [mtlEncoder drawPrimitives:_mtlPrimitiveType - vertexStart:info.firstVertex - vertexCount:info.vertexCount - instanceCount:info.instanceCount]; - } + } else if (info.vertexCount) { + if (info.instanceCount == 0) { + [mtlEncoder drawPrimitives:_mtlPrimitiveType + vertexStart:info.firstVertex + vertexCount:info.vertexCount]; + } else { + [mtlEncoder drawPrimitives:_mtlPrimitiveType + vertexStart:info.firstVertex + vertexCount:info.vertexCount + instanceCount:info.instanceCount]; } + } - _numInstances += info.instanceCount; - _numDrawCalls++; - if (_gpuCommandBufferObj->pipelineState) { - uint32_t indexCount = info.indexCount ? info.indexCount : info.vertexCount; - switch (_mtlPrimitiveType) { - case MTLPrimitiveTypeTriangle: - _numTriangles += indexCount / 3 * std::max(info.instanceCount, 1U); - break; - case MTLPrimitiveTypeTriangleStrip: - _numTriangles += (indexCount - 2) * std::max(info.instanceCount, 1U); - break; - default: break; - } + _numInstances += info.instanceCount; + _numDrawCalls++; + if (_gpuCommandBufferObj->pipelineState) { + uint32_t indexCount = info.indexCount ? info.indexCount : info.vertexCount; + switch (_mtlPrimitiveType) { + case MTLPrimitiveTypeTriangle: + _numTriangles += indexCount / 3 * std::max(info.instanceCount, 1U); + break; + case MTLPrimitiveTypeTriangleStrip: + _numTriangles += (indexCount - 2) * std::max(info.instanceCount, 1U); + break; + default: break; } } } @@ -933,6 +909,25 @@ of this software and associated engine source code (the "Software"), a limited, blitTexture(srcTexture, dstTexture, blitRegions.data(), count, Filter::POINT); } +void CCMTLCommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + id cmdBuffer = getMTLCommandBuffer(); + id encoder = [cmdBuffer blitCommandEncoder]; + + auto *ccSrcBuffer = static_cast(srcBuffer); + auto *ccDstBuffer = static_cast(dstBuffer); + + for (uint32_t i = 0; i < count; ++i) { + const auto © = regions[i]; + [encoder copyFromBuffer: ccSrcBuffer->mtlBuffer() + sourceOffset: ccSrcBuffer->currentOffset() + copy.srcOffset + toBuffer: ccDstBuffer->mtlBuffer() + destinationOffset: ccDstBuffer->currentOffset() + copy.dstOffset + size: copy.size]; + } + + [encoder endEncoding]; +} + void CCMTLCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { if (srcTexture && dstTexture && regions) { id cmdBuffer = getMTLCommandBuffer(); diff --git a/native/cocos/renderer/gfx-validator/BufferValidator.cpp b/native/cocos/renderer/gfx-validator/BufferValidator.cpp index a6e5f691b05..a2ed6d279cf 100644 --- a/native/cocos/renderer/gfx-validator/BufferValidator.cpp +++ b/native/cocos/renderer/gfx-validator/BufferValidator.cpp @@ -145,18 +145,6 @@ void BufferValidator::update(const void *buffer, uint32_t size) { CC_ASSERT(size && size <= _size); CC_ASSERT(buffer); - if (hasFlag(_usage, BufferUsageBit::INDIRECT)) { - const auto *drawInfo = static_cast(buffer); - const size_t drawInfoCount = size / sizeof(DrawInfo); - const bool isIndexed = drawInfoCount > 0 && drawInfo->indexCount > 0; - for (size_t i = 1U; i < drawInfoCount; ++i) { - if ((++drawInfo)->indexCount > 0 != isIndexed) { - // Inconsistent indirect draw infos on using index buffer. - CC_ABORT(); - } - } - } - sanityCheck(buffer, size); ++_totalUpdateTimes; // only count direct updates diff --git a/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp b/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp index bab7e3c6ca5..3b584ca7cb0 100644 --- a/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp +++ b/native/cocos/renderer/gfx-validator/CommandBufferValidator.cpp @@ -384,6 +384,32 @@ void CommandBufferValidator::draw(const DrawInfo &info) { _actor->draw(info); } +void CommandBufferValidator::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) +{ + CC_ASSERT(stride == (sizeof(DrawIndirectCommand))); + CC_ASSERT(isInited()); + CC_ASSERT(buffer); + CC_ASSERT(hasFlag(buffer->getUsage(), BufferUsageBit::INDIRECT)); + + auto *bufferValidator = static_cast(buffer); + CC_ASSERT(bufferValidator->isInited()); + + _actor->drawIndirect(bufferValidator->getActor(), offset, count, stride); +} + +void CommandBufferValidator::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) +{ + CC_ASSERT(stride == (sizeof(DrawIndexedIndirectCommand))); + CC_ASSERT(isInited()); + CC_ASSERT(buffer); + CC_ASSERT(hasFlag(buffer->getUsage(), BufferUsageBit::INDIRECT)); + + auto *bufferValidator = static_cast(buffer); + CC_ASSERT(bufferValidator->isInited()); + + _actor->drawIndexedIndirect(bufferValidator->getActor(), offset, count, stride); +} + void CommandBufferValidator::updateBuffer(Buffer *buff, const void *data, uint32_t size) { CC_ASSERT(isInited()); CC_ASSERT(buff && static_cast(buff)->isInited()); @@ -483,6 +509,31 @@ void CommandBufferValidator::copyTexture(Texture *srcTexture, Texture *dstTextur _actor->copyTexture(actorSrcTexture, actorDstTexture, regions, count); } +void CommandBufferValidator::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + CC_ASSERT(isInited()); + CC_ASSERT(srcBuffer && static_cast(srcBuffer)->isInited()); + CC_ASSERT(dstBuffer && static_cast(dstBuffer)->isInited()); + const auto &srcSize = dstBuffer->getSize(); + const auto &dstSize = srcBuffer->getSize(); + + CC_ASSERT(!_insideRenderPass); + + for (uint32_t i = 0; i < count; ++i) { + const auto ®ion = regions[i]; + CC_ASSERT(region.srcOffset + region.size <= srcSize); + CC_ASSERT(region.dstOffset + region.size <= dstSize); + } + + /////////// execute /////////// + + Buffer *actorSrcBuffer = nullptr; + Buffer *actorDstBuffer = nullptr; + if (srcBuffer) actorSrcBuffer = static_cast(srcBuffer)->getActor(); + if (dstBuffer) actorDstBuffer = static_cast(dstBuffer)->getActor(); + + _actor->copyBuffer(actorSrcBuffer, actorDstBuffer, regions, count); +} + void CommandBufferValidator::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { CC_ASSERT(isInited()); CC_ASSERT(srcTexture && static_cast(srcTexture)->isInited()); diff --git a/native/cocos/renderer/gfx-validator/CommandBufferValidator.h b/native/cocos/renderer/gfx-validator/CommandBufferValidator.h index 3ec70240be2..264f3539aa3 100644 --- a/native/cocos/renderer/gfx-validator/CommandBufferValidator.h +++ b/native/cocos/renderer/gfx-validator/CommandBufferValidator.h @@ -54,11 +54,14 @@ class CC_DLL CommandBufferValidator final : public Agent { void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buff, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-validator/InputAssemblerValidator.cpp b/native/cocos/renderer/gfx-validator/InputAssemblerValidator.cpp index 8b76576de31..f6b104ac014 100644 --- a/native/cocos/renderer/gfx-validator/InputAssemblerValidator.cpp +++ b/native/cocos/renderer/gfx-validator/InputAssemblerValidator.cpp @@ -60,10 +60,6 @@ void InputAssemblerValidator::doInit(const InputAssemblerInfo &info) { CC_ASSERT(static_cast(info.indexBuffer)->isInited()); CC_ASSERT(hasFlag(info.indexBuffer->getUsage(), BufferUsageBit::INDEX)); } - if (info.indirectBuffer) { - CC_ASSERT(static_cast(info.indirectBuffer)->isInited()); - CC_ASSERT(hasFlag(info.indirectBuffer->getUsage(), BufferUsageBit::INDIRECT)); - } /////////// execute /////////// @@ -74,9 +70,6 @@ void InputAssemblerValidator::doInit(const InputAssemblerInfo &info) { if (actorInfo.indexBuffer) { actorInfo.indexBuffer = static_cast(actorInfo.indexBuffer)->getActor(); } - if (actorInfo.indirectBuffer) { - actorInfo.indirectBuffer = static_cast(actorInfo.indirectBuffer)->getActor(); - } _actor->initialize(actorInfo); } diff --git a/native/cocos/renderer/gfx-vulkan/VKBuffer.cpp b/native/cocos/renderer/gfx-vulkan/VKBuffer.cpp index 63f4e1e114d..620523b0bf0 100644 --- a/native/cocos/renderer/gfx-vulkan/VKBuffer.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKBuffer.cpp @@ -101,12 +101,6 @@ void CCVKGPUBuffer::shutdown() { } void CCVKGPUBuffer::init() { - if (hasFlag(usage, BufferUsageBit::INDIRECT)) { - const size_t drawInfoCount = size / sizeof(DrawInfo); - indexedIndirectCmds.resize(drawInfoCount); - indirectCmds.resize(drawInfoCount); - } - cmdFuncCCVKCreateBuffer(CCVKDevice::getInstance(), this); CCVKDevice::getInstance()->getMemoryStatus().bufferSize += size; CC_PROFILE_MEMORY_INC(Buffer, size); diff --git a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp index 7aefa9312fc..6fe3dcd0e27 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.cpp @@ -408,77 +408,94 @@ void CCVKCommandBuffer::nextSubpass() { _hasSubPassSelfDependency = _curGPURenderPass->hasSelfDependency[_currentSubPass]; } -void CCVKCommandBuffer::draw(const DrawInfo &info) { - CC_PROFILE(CCVKCmdBufDraw); +void CCVKCommandBuffer::drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { if (_firstDirtyDescriptorSet < _curGPUDescriptorSets.size()) { bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS); } - const auto *gpuIndirectBuffer = _curGPUInputAssembler->gpuIndirectBuffer.get(); + auto *vkBuffer = static_cast(buffer); + auto *gpuBuffer = vkBuffer->gpuBufferView(); - if (gpuIndirectBuffer) { - uint32_t drawInfoCount = gpuIndirectBuffer->range / gpuIndirectBuffer->gpuBuffer->stride; - CCVKGPUDevice *gpuDevice = CCVKDevice::getInstance()->gpuDevice(); - VkDeviceSize offset = gpuIndirectBuffer->getStartOffset(gpuDevice->curBackBufferIndex); - if (gpuDevice->useMultiDrawIndirect) { - if (gpuIndirectBuffer->gpuBuffer->isDrawIndirectByIndex) { - vkCmdDrawIndexedIndirect(_gpuCommandBuffer->vkCommandBuffer, - gpuIndirectBuffer->gpuBuffer->vkBuffer, - offset, - drawInfoCount, - sizeof(VkDrawIndexedIndirectCommand)); - } else { - vkCmdDrawIndirect(_gpuCommandBuffer->vkCommandBuffer, - gpuIndirectBuffer->gpuBuffer->vkBuffer, - offset, - drawInfoCount, - sizeof(VkDrawIndirectCommand)); - } - } else { - if (gpuIndirectBuffer->gpuBuffer->isDrawIndirectByIndex) { - for (VkDeviceSize j = 0U; j < drawInfoCount; ++j) { - vkCmdDrawIndexedIndirect(_gpuCommandBuffer->vkCommandBuffer, - gpuIndirectBuffer->gpuBuffer->vkBuffer, - offset + j * sizeof(VkDrawIndexedIndirectCommand), - 1, - sizeof(VkDrawIndexedIndirectCommand)); - } - } else { - for (VkDeviceSize j = 0U; j < drawInfoCount; ++j) { - vkCmdDrawIndirect(_gpuCommandBuffer->vkCommandBuffer, - gpuIndirectBuffer->gpuBuffer->vkBuffer, - offset + j * sizeof(VkDrawIndirectCommand), - 1, - sizeof(VkDrawIndirectCommand)); - } - } - } + CCVKGPUDevice *gpuDevice = CCVKDevice::getInstance()->gpuDevice(); + uint32_t bufferOffset = gpuBuffer->getStartOffset(gpuDevice->curBackBufferIndex); + + if (gpuDevice->useMultiDrawIndirect) { + vkCmdDrawIndirect(_gpuCommandBuffer->vkCommandBuffer, + vkBuffer->gpuBuffer()->vkBuffer, + bufferOffset + offset, + count, + stride); } else { - uint32_t instanceCount = std::max(info.instanceCount, 1U); - bool hasIndexBuffer = _curGPUInputAssembler->gpuIndexBuffer && info.indexCount > 0; + for (uint32_t i = 0U; i < count; ++i) { + uint32_t currentOffset = bufferOffset + offset + i * stride; + vkCmdDrawIndirect(_gpuCommandBuffer->vkCommandBuffer, + vkBuffer->gpuBuffer()->vkBuffer, + currentOffset, + 1, + stride); + } + } +} - if (hasIndexBuffer) { - vkCmdDrawIndexed(_gpuCommandBuffer->vkCommandBuffer, info.indexCount, instanceCount, - info.firstIndex, info.vertexOffset, info.firstInstance); - } else { - vkCmdDraw(_gpuCommandBuffer->vkCommandBuffer, info.vertexCount, instanceCount, - info.firstVertex, info.firstInstance); +void CCVKCommandBuffer::drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) { + if (_firstDirtyDescriptorSet < _curGPUDescriptorSets.size()) { + bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS); + } + + auto *vkBuffer = static_cast(buffer); + auto *gpuBuffer = vkBuffer->gpuBufferView(); + + CCVKGPUDevice *gpuDevice = CCVKDevice::getInstance()->gpuDevice(); + uint32_t bufferOffset = gpuBuffer->getStartOffset(gpuDevice->curBackBufferIndex); + + if (gpuDevice->useMultiDrawIndirect) { + vkCmdDrawIndexedIndirect(_gpuCommandBuffer->vkCommandBuffer, + vkBuffer->gpuBuffer()->vkBuffer, + bufferOffset + offset, + count, + stride); + } else { + for (uint32_t i = 0U; i < count; ++i) { + uint32_t currentOffset = bufferOffset + offset + i * stride; + vkCmdDrawIndexedIndirect(_gpuCommandBuffer->vkCommandBuffer, + vkBuffer->gpuBuffer()->vkBuffer, + currentOffset, + 1, + stride); } + } +} - ++_numDrawCalls; - _numInstances += info.instanceCount; - if (_curGPUPipelineState) { - uint32_t indexCount = hasIndexBuffer ? info.indexCount : info.vertexCount; - switch (_curGPUPipelineState->primitive) { - case PrimitiveMode::TRIANGLE_LIST: - _numTriangles += indexCount / 3 * instanceCount; - break; - case PrimitiveMode::TRIANGLE_STRIP: - case PrimitiveMode::TRIANGLE_FAN: - _numTriangles += (indexCount - 2) * instanceCount; - break; - default: break; - } +void CCVKCommandBuffer::draw(const DrawInfo &info) { + CC_PROFILE(CCVKCmdBufDraw); + if (_firstDirtyDescriptorSet < _curGPUDescriptorSets.size()) { + bindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS); + } + + uint32_t instanceCount = std::max(info.instanceCount, 1U); + bool hasIndexBuffer = _curGPUInputAssembler->gpuIndexBuffer && info.indexCount > 0; + + if (hasIndexBuffer) { + vkCmdDrawIndexed(_gpuCommandBuffer->vkCommandBuffer, info.indexCount, instanceCount, + info.firstIndex, info.vertexOffset, info.firstInstance); + } else { + vkCmdDraw(_gpuCommandBuffer->vkCommandBuffer, info.vertexCount, instanceCount, + info.firstVertex, info.firstInstance); + } + + ++_numDrawCalls; + _numInstances += info.instanceCount; + if (_curGPUPipelineState) { + uint32_t indexCount = hasIndexBuffer ? info.indexCount : info.vertexCount; + switch (_curGPUPipelineState->primitive) { + case PrimitiveMode::TRIANGLE_LIST: + _numTriangles += indexCount / 3 * instanceCount; + break; + case PrimitiveMode::TRIANGLE_STRIP: + case PrimitiveMode::TRIANGLE_FAN: + _numTriangles += (indexCount - 2) * instanceCount; + break; + default: break; } } if (_hasSubPassSelfDependency) { @@ -606,6 +623,22 @@ void CCVKCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, co vkCmdCopyImage(_gpuCommandBuffer->vkCommandBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, count, copyRegions.data()); } +void CCVKCommandBuffer::copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) { + CCVKGPUBuffer *gpuSrcBuffer = static_cast(srcBuffer)->gpuBuffer(); + CCVKGPUBuffer *gpuDstBuffer = static_cast(dstBuffer)->gpuBuffer(); + + ccstd::vector copyRegions(count, VkBufferCopy{}); + for (uint32_t i = 0U; i < count; ++i) { + const BufferCopy ®ion = regions[i]; + auto ©Region = copyRegions[i]; + + copyRegion.srcOffset = static_cast(region.srcOffset); + copyRegion.dstOffset = static_cast(region.dstOffset); + copyRegion.size = static_cast(region.size); + } + vkCmdCopyBuffer(_gpuCommandBuffer->vkCommandBuffer, gpuSrcBuffer->vkBuffer, gpuDstBuffer->vkBuffer, count, copyRegions.data()); +} + void CCVKCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) { VkImageAspectFlags srcAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; VkImageAspectFlags dstAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; diff --git a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h index 1eae85158ed..16a5fb333e9 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h +++ b/native/cocos/renderer/gfx-vulkan/VKCommandBuffer.h @@ -54,11 +54,14 @@ class CC_VULKAN_API CCVKCommandBuffer final : public CommandBuffer { void setStencilCompareMask(StencilFace face, uint32_t reference, uint32_t mask) override; void nextSubpass() override; void draw(const DrawInfo &info) override; + void drawIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; + void drawIndexedIndirect(Buffer *buffer, uint32_t offset, uint32_t count, uint32_t stride) override; void updateBuffer(Buffer *buffer, const void *data, uint32_t size) override; void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override; void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override; void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override; + void copyBuffer(Buffer *srcBuffer, Buffer *dstBuffer, const BufferCopy *regions, uint32_t count) override; void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override; void dispatch(const DispatchInfo &info) override; void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override; diff --git a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp index cf098298382..65b139effa4 100644 --- a/native/cocos/renderer/gfx-vulkan/VKCommands.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKCommands.cpp @@ -1208,42 +1208,8 @@ void bufferUpload(const CCVKGPUBufferView &stagingBuffer, CCVKGPUBuffer &gpuBuff void cmdFuncCCVKUpdateBuffer(CCVKDevice *device, CCVKGPUBuffer *gpuBuffer, const void *buffer, uint32_t size, const CCVKGPUCommandBuffer *cmdBuffer) { if (!gpuBuffer) return; - const void *dataToUpload = nullptr; - size_t sizeToUpload = 0U; - - if (hasFlag(gpuBuffer->usage, BufferUsageBit::INDIRECT)) { - size_t drawInfoCount = size / sizeof(DrawInfo); - const auto *drawInfo = static_cast(buffer); - if (drawInfoCount > 0) { - if (drawInfo->indexCount) { - for (size_t i = 0; i < drawInfoCount; ++i) { - gpuBuffer->indexedIndirectCmds[i].indexCount = drawInfo->indexCount; - gpuBuffer->indexedIndirectCmds[i].instanceCount = std::max(drawInfo->instanceCount, 1U); - gpuBuffer->indexedIndirectCmds[i].firstIndex = drawInfo->firstIndex; - gpuBuffer->indexedIndirectCmds[i].vertexOffset = drawInfo->vertexOffset; - gpuBuffer->indexedIndirectCmds[i].firstInstance = drawInfo->firstInstance; - drawInfo++; - } - dataToUpload = gpuBuffer->indexedIndirectCmds.data(); - sizeToUpload = drawInfoCount * sizeof(VkDrawIndexedIndirectCommand); - gpuBuffer->isDrawIndirectByIndex = true; - } else { - for (size_t i = 0; i < drawInfoCount; ++i) { - gpuBuffer->indirectCmds[i].vertexCount = drawInfo->vertexCount; - gpuBuffer->indirectCmds[i].instanceCount = std::max(drawInfo->instanceCount, 1U); - gpuBuffer->indirectCmds[i].firstVertex = drawInfo->firstVertex; - gpuBuffer->indirectCmds[i].firstInstance = drawInfo->firstInstance; - drawInfo++; - } - dataToUpload = gpuBuffer->indirectCmds.data(); - sizeToUpload = drawInfoCount * sizeof(VkDrawIndirectCommand); - gpuBuffer->isDrawIndirectByIndex = false; - } - } - } else { - dataToUpload = buffer; - sizeToUpload = size; - } + const void *dataToUpload = buffer; + size_t sizeToUpload = size; // back buffer instances update command uint32_t backBufferIndex = device->gpuDevice()->curBackBufferIndex; diff --git a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp index 85d9bacdfcb..3dc767fa6eb 100644 --- a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp @@ -821,6 +821,8 @@ void CCVKDevice::initExtensionCapability() { _caps.supportVariableRateShading &= hasFlag(_formatFeatures[static_cast(Format::R8UI)], FormatFeatureBit::SHADING_RATE); _caps.supportSubPassShading = checkExtension(VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME); + _caps.supportMultiDrawIndirect = _gpuContext->physicalDeviceFeatures.multiDrawIndirect && + _gpuContext->physicalDeviceFeatures.drawIndirectFirstInstance; } CommandBuffer *CCVKDevice::createCommandBuffer(const CommandBufferInfo & /*info*/, bool /*hasAgent*/) { diff --git a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h index cb386223c67..22e3551a32c 100644 --- a/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h +++ b/native/cocos/renderer/gfx-vulkan/VKGPUObjects.h @@ -222,10 +222,6 @@ struct CCVKGPUBuffer : public CCVKGPUDeviceObject { uint32_t count = 0U; void *buffer = nullptr; - bool isDrawIndirectByIndex = false; - ccstd::vector indirectCmds; - ccstd::vector indexedIndirectCmds; - uint8_t *mappedData = nullptr; VmaAllocation vmaAllocation = VK_NULL_HANDLE; @@ -341,7 +337,6 @@ struct CCVKGPUInputAssembler : public CCVKGPUDeviceObject { AttributeList attributes; ccstd::vector> gpuVertexBuffers; ConstPtr gpuIndexBuffer; - ConstPtr gpuIndirectBuffer; ccstd::vector vertexBuffers; ccstd::vector vertexBufferOffsets; }; diff --git a/native/cocos/renderer/gfx-vulkan/VKInputAssembler.cpp b/native/cocos/renderer/gfx-vulkan/VKInputAssembler.cpp index f7dae717a66..6b1f5a1b638 100644 --- a/native/cocos/renderer/gfx-vulkan/VKInputAssembler.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKInputAssembler.cpp @@ -57,11 +57,6 @@ void CCVKInputAssembler::doInit(const InputAssemblerInfo &info) { hub->connect(_gpuInputAssembler, _gpuInputAssembler->gpuIndexBuffer.get()); } - if (info.indirectBuffer) { - _gpuInputAssembler->gpuIndirectBuffer = static_cast(info.indirectBuffer)->gpuBufferView(); - hub->connect(_gpuInputAssembler, _gpuInputAssembler->gpuIndirectBuffer.get()); - } - _gpuInputAssembler->vertexBuffers.resize(vbCount); _gpuInputAssembler->vertexBufferOffsets.resize(vbCount); @@ -84,9 +79,6 @@ void CCVKGPUInputAssembler::shutdown() { if (gpuIndexBuffer) { hub->disengage(this, gpuIndexBuffer); } - if (gpuIndirectBuffer) { - hub->disengage(this, gpuIndirectBuffer); - } } void CCVKGPUInputAssembler::update(const CCVKGPUBufferView *oldBuffer, const CCVKGPUBufferView *newBuffer) { @@ -99,9 +91,6 @@ void CCVKGPUInputAssembler::update(const CCVKGPUBufferView *oldBuffer, const CCV if (gpuIndexBuffer.get() == oldBuffer) { gpuIndexBuffer = newBuffer; } - if (gpuIndirectBuffer.get() == oldBuffer) { - gpuIndirectBuffer = newBuffer; - } } } // namespace gfx diff --git a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp index 23fdda466bc..c931a76bc52 100644 --- a/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp +++ b/native/cocos/renderer/pipeline/custom/NativeExecutor.cpp @@ -1441,10 +1441,23 @@ struct RenderGraphVisitor : boost::dfs_visitor<> { const CopyPair& copy, ResourceGraph::vertex_descriptor srcID, ResourceGraph::vertex_descriptor dstID) const { - // TODO(zhouzhenglong): add impl - std::ignore = copy; - std::ignore = srcID; - std::ignore = dstID; + auto& resg = ctx.resourceGraph; + std::vector copyInfos(1, gfx::BufferCopy{}); + + gfx::Buffer* srcBuffer = resg.getBuffer(srcID); + gfx::Buffer* dstBuffer = resg.getBuffer(dstID); + CC_ENSURES(srcBuffer); + CC_ENSURES(dstBuffer); + if (!srcBuffer || !dstBuffer) { + return; + } + + auto& copyInfo = copyInfos[0]; + copyInfo.srcOffset = copy.sourceOffset; + copyInfo.dstOffset = copy.targetOffset; + copyInfo.size = copy.bufferSize; + + ctx.cmdBuff->copyBuffer(srcBuffer, dstBuffer, copyInfos.data(), 1); } void uploadTexture( // NOLINT(readability-convert-member-functions-to-static) const UploadPair& upload, diff --git a/native/cocos/renderer/pipeline/xr/ar/ARBackground.cpp b/native/cocos/renderer/pipeline/xr/ar/ARBackground.cpp index 137ca304310..130554450af 100644 --- a/native/cocos/renderer/pipeline/xr/ar/ARBackground.cpp +++ b/native/cocos/renderer/pipeline/xr/ar/ARBackground.cpp @@ -201,22 +201,10 @@ void ARBackground::activate(RenderPipeline *pipeline, gfx::Device *dev) { auto *indexBuffer = _device->createBuffer(indexBufferInfo); indexBuffer->update(indices, sizeof(indices)); - gfx::DrawInfo drawInfo; - drawInfo.indexCount = 6; - gfx::BufferInfo indirectBufferInfo = { - gfx::BufferUsageBit::INDIRECT, - gfx::MemoryUsage::DEVICE, - sizeof(gfx::DrawInfo), - sizeof(gfx::DrawInfo), - }; - auto *indirectBuffer = _device->createBuffer(indirectBufferInfo); - indirectBuffer->update(&drawInfo, sizeof(gfx::DrawInfo)); - - gfx::InputAssemblerInfo inputAssemblerInfo; + gfx::InputAssemblerInfo inputAssemblerInfo = {}; inputAssemblerInfo.attributes = std::move(attributeList); inputAssemblerInfo.vertexBuffers.emplace_back(_vertexBuffer); inputAssemblerInfo.indexBuffer = indexBuffer; - inputAssemblerInfo.indirectBuffer = indirectBuffer; _inputAssembler = _device->createInputAssembler(inputAssemblerInfo); #pragma endregion @@ -380,10 +368,14 @@ void ARBackground::render(cc::scene::Camera *camera, gfx::RenderPass *renderPass _pipelineState = _device->createPipelineState(pipelineInfo); + gfx::DrawInfo drawInfo; + drawInfo.indexCount = 6; + cmdBuffer->bindInputAssembler(_inputAssembler); cmdBuffer->bindPipelineState(_pipelineState); cmdBuffer->bindDescriptorSet(materialSet, _descriptorSet); - cmdBuffer->draw(_inputAssembler); + cmdBuffer->bindInputAssembler(_inputAssembler); + cmdBuffer->draw(drawInfo); } template diff --git a/native/tools/swig-config/gfx.i b/native/tools/swig-config/gfx.i index a0944e0ffd7..f9d11caf6b5 100644 --- a/native/tools/swig-config/gfx.i +++ b/native/tools/swig-config/gfx.i @@ -67,6 +67,8 @@ namespace cc { namespace gfx { %ignore CommandBuffer::updateBuffer; %ignore CommandBuffer::resolveTexture; %ignore CommandBuffer::copyBuffersToTexture; +%ignore CommandBuffer::drawIndirect; +%ignore CommandBuffer::drawIndexedIndirect; %rename(drawWithInfo) CommandBuffer::draw(const DrawInfo&); %ignore DescriptorSetLayout::getBindingIndices; @@ -183,7 +185,6 @@ namespace cc { namespace gfx { %attribute(cc::gfx::InputAssembler, cc::gfx::BufferList&, vertexBuffers, getVertexBuffers); %attribute(cc::gfx::InputAssembler, cc::gfx::AttributeList&, attributes, getAttributes); %attribute(cc::gfx::InputAssembler, cc::gfx::Buffer*, indexBuffer, getIndexBuffer); -%attribute(cc::gfx::InputAssembler, cc::gfx::Buffer*, indirectBuffer, getIndirectBuffer); %attribute(cc::gfx::InputAssembler, uint32_t, attributesHash, getAttributesHash); %attribute(cc::gfx::InputAssembler, cc::gfx::DrawInfo&, drawInfo, getDrawInfo, setDrawInfo); From 9a3b37995bf02d2f48c650de3e504dbedb17a174 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 19 Jul 2023 11:41:48 +0800 Subject: [PATCH 56/57] fix eslint --- cocos/asset/assets/rendering-sub-mesh.ts | 24 +++++++++++++++------- cocos/gfx/webgl/webgl-buffer.ts | 5 +++-- cocos/gfx/webgl/webgl-gpu-objects.ts | 19 ++++++++++++----- cocos/gfx/webgl/webgl-input-assembler.ts | 5 +++-- cocos/gfx/webgl2/webgl2-buffer.ts | 5 +++-- cocos/gfx/webgl2/webgl2-input-assembler.ts | 5 +++-- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/cocos/asset/assets/rendering-sub-mesh.ts b/cocos/asset/assets/rendering-sub-mesh.ts index 857a7161d3a..439539bde8c 100644 --- a/cocos/asset/assets/rendering-sub-mesh.ts +++ b/cocos/asset/assets/rendering-sub-mesh.ts @@ -135,8 +135,11 @@ export class RenderingSubMesh { * @param indirectBuffer @en indirect buffer. @zh 间接缓冲区。 */ constructor ( - vertexBuffers: Buffer[], attributes: Attribute[], primitiveMode: PrimitiveMode, - indexBuffer: Buffer | null = null, indirectBuffer: Buffer | null = null, + vertexBuffers: Buffer[], + attributes: Attribute[], + primitiveMode: PrimitiveMode, + indexBuffer: Buffer | null = null, + indirectBuffer: Buffer | null = null, isOwnerOfIndexBuffer = true, ) { this._attributes = attributes; @@ -197,7 +200,7 @@ export class RenderingSubMesh { const indices = mesh.readIndices(index) as Uint16Array; const max = new Vec3(); const min = new Vec3(); - const pAttri = this.attributes.find((element): boolean => element.name === AttributeName.ATTR_POSITION); + const pAttri = this.attributes.find((element): boolean => element.name === AttributeName.ATTR_POSITION as string); if (pAttri) { const conut = FormatInfos[pAttri.format].count; if (conut === 2) { @@ -307,14 +310,14 @@ export class RenderingSubMesh { } let jointFormat: Format; let jointOffset: number; - const { device } = cclegacy.director.root; + const device = cclegacy.director.root.device as Device; for (let i = 0; i < prim.vertexBundelIndices.length; i++) { const bundle = struct.vertexBundles[prim.vertexBundelIndices[i]]; jointOffset = 0; jointFormat = Format.UNKNOWN; for (let j = 0; j < bundle.attributes.length; j++) { const attr = bundle.attributes[j]; - if (attr.name === AttributeName.ATTR_JOINTS) { + if (attr.name === AttributeName.ATTR_JOINTS as string) { jointFormat = attr.format; break; } @@ -324,8 +327,15 @@ export class RenderingSubMesh { const data = new Uint8Array(this.mesh.data.buffer, bundle.view.offset, bundle.view.length); const dataView = new DataView(data.slice().buffer); const idxMap = struct.jointMaps[prim.jointMapIndex]; - mapBuffer(dataView, (cur): number => idxMap.indexOf(cur), jointFormat, jointOffset, - bundle.view.length, bundle.view.stride, dataView); + mapBuffer( + dataView, + (cur): number => idxMap.indexOf(cur), + jointFormat, + jointOffset, + bundle.view.length, + bundle.view.stride, + dataView, + ); const buffer = device.createBuffer(new BufferInfo( BufferUsageBit.VERTEX | BufferUsageBit.TRANSFER_DST, MemoryUsageBit.DEVICE, diff --git a/cocos/gfx/webgl/webgl-buffer.ts b/cocos/gfx/webgl/webgl-buffer.ts index a4533b76dea..508e3e9c8c9 100644 --- a/cocos/gfx/webgl/webgl-buffer.ts +++ b/cocos/gfx/webgl/webgl-buffer.ts @@ -33,6 +33,7 @@ import { } from './webgl-commands'; import { IWebGLGPUBuffer, IWebGLGPUBufferView, WebGLIndirectDrawInfos } from './webgl-gpu-objects'; import { WebGLDeviceManager } from './webgl-define'; +import { warn } from '../../core/platform'; export class WebGLBuffer extends Buffer { get gpuBuffer (): IWebGLGPUBuffer { @@ -111,7 +112,7 @@ export class WebGLBuffer extends Buffer { public resize (size: number): void { if (this._isBufferView) { - console.warn('cannot resize buffer views!'); + warn('cannot resize buffer views!'); return; } @@ -141,7 +142,7 @@ export class WebGLBuffer extends Buffer { public update (buffer: Readonly, size?: number): void { if (this._isBufferView) { - console.warn('cannot update through buffer views!'); + warn('cannot update through buffer views!'); return; } diff --git a/cocos/gfx/webgl/webgl-gpu-objects.ts b/cocos/gfx/webgl/webgl-gpu-objects.ts index 83350acaa67..aa3e112e32a 100644 --- a/cocos/gfx/webgl/webgl-gpu-objects.ts +++ b/cocos/gfx/webgl/webgl-gpu-objects.ts @@ -339,12 +339,16 @@ export class IWebGLBlitManager { this._gpuShader = { name: 'Blit Pass', blocks: [ - new UniformBlock(0, 0, `BlitParams`, + new UniformBlock( + 0, + 0, + `BlitParams`, [ new Uniform(`tilingOffsetSrc`, Type.FLOAT4, 1), new Uniform(`tilingOffsetDst`, Type.FLOAT4, 1), ], - 1), + 1, + ), ], samplerTextures: [new UniformSamplerTexture(0, samplerOffset, 'textureSrc', Type.SAMPLER2D, 1)], subpassInputs: [], @@ -533,7 +537,7 @@ export class IWebGLBlitManager { descriptor.gpuSampler = filter === Filter.POINT ? this._gpuPointSampler : this._gpuLinearSampler; const formatInfo = FormatInfos[gpuTextureDst.format]; - let attachment = gl.COLOR_ATTACHMENT0; + let attachment: number = gl.COLOR_ATTACHMENT0; if (formatInfo.hasStencil) { attachment = gl.DEPTH_STENCIL_ATTACHMENT; } else if (formatInfo.hasDepth) { @@ -577,8 +581,13 @@ export class IWebGLBlitManager { this._uniformBuffer[6] = region.dstOffset.x / dstWidth; this._uniformBuffer[7] = region.dstOffset.y / dstHeight; - WebGLCmdFuncUpdateBuffer(device, this._gpuUniformBuffer, this._uniformBuffer, 0, - this._uniformBuffer.length * Float32Array.BYTES_PER_ELEMENT); + WebGLCmdFuncUpdateBuffer( + device, + this._gpuUniformBuffer, + this._uniformBuffer, + 0, + this._uniformBuffer.length * Float32Array.BYTES_PER_ELEMENT, + ); WebGLCmdFuncBindStates(device, this._gpuPipelineState, this._gpuInputAssembler, [this._gpuDescriptorSet], [], null!); WebGLCmdFuncDraw(device, this._drawInfo); } diff --git a/cocos/gfx/webgl/webgl-input-assembler.ts b/cocos/gfx/webgl/webgl-input-assembler.ts index 4208609de41..1d5a82bcc21 100644 --- a/cocos/gfx/webgl/webgl-input-assembler.ts +++ b/cocos/gfx/webgl/webgl-input-assembler.ts @@ -22,6 +22,7 @@ THE SOFTWARE. */ +import { error } from '../../core/platform'; import { InputAssemblerInfo } from '../base/define'; import { InputAssembler } from '../base/input-assembler'; import { WebGLBuffer } from './webgl-buffer'; @@ -38,7 +39,7 @@ export class WebGLInputAssembler extends InputAssembler { public initialize (info: Readonly): void { if (info.vertexBuffers.length === 0) { - console.error('InputAssemblerInfo.vertexBuffers is null.'); + error('InputAssemblerInfo.vertexBuffers is null.'); return; } @@ -77,7 +78,7 @@ export class WebGLInputAssembler extends InputAssembler { case 2: glIndexType = 0x1403; break; // WebGLRenderingContext.UNSIGNED_SHORT case 4: glIndexType = 0x1405; break; // WebGLRenderingContext.UNSIGNED_INT default: { - console.error('Error index buffer stride.'); + error('Error index buffer stride.'); } } } diff --git a/cocos/gfx/webgl2/webgl2-buffer.ts b/cocos/gfx/webgl2/webgl2-buffer.ts index 53fbffabcc0..e119230ff21 100644 --- a/cocos/gfx/webgl2/webgl2-buffer.ts +++ b/cocos/gfx/webgl2/webgl2-buffer.ts @@ -22,6 +22,7 @@ THE SOFTWARE. */ +import { warn } from '../../core/platform'; import { Buffer } from '../base/buffer'; import { BufferUsageBit, BufferSource, BufferInfo, BufferViewInfo } from '../base/define'; import { @@ -99,7 +100,7 @@ export class WebGL2Buffer extends Buffer { public resize (size: number): void { if (this._isBufferView) { - console.warn('cannot resize buffer views!'); + warn('cannot resize buffer views!'); return; } @@ -121,7 +122,7 @@ export class WebGL2Buffer extends Buffer { public update (buffer: Readonly, size?: number): void { if (this._isBufferView) { - console.warn('cannot update through buffer views!'); + warn('cannot update through buffer views!'); return; } diff --git a/cocos/gfx/webgl2/webgl2-input-assembler.ts b/cocos/gfx/webgl2/webgl2-input-assembler.ts index 0b927925d9f..5f7859851bf 100644 --- a/cocos/gfx/webgl2/webgl2-input-assembler.ts +++ b/cocos/gfx/webgl2/webgl2-input-assembler.ts @@ -22,6 +22,7 @@ THE SOFTWARE. */ +import { error } from '../../core/platform'; import { InputAssemblerInfo } from '../base/define'; import { InputAssembler } from '../base/input-assembler'; import { WebGL2Buffer } from './webgl2-buffer'; @@ -38,7 +39,7 @@ export class WebGL2InputAssembler extends InputAssembler { public initialize (info: Readonly): void { if (info.vertexBuffers.length === 0) { - console.error('InputAssemblerInfo.vertexBuffers is null.'); + error('InputAssemblerInfo.vertexBuffers is null.'); return; } @@ -77,7 +78,7 @@ export class WebGL2InputAssembler extends InputAssembler { case 2: glIndexType = 0x1403; break; // WebGLRenderingContext.UNSIGNED_SHORT case 4: glIndexType = 0x1405; break; // WebGLRenderingContext.UNSIGNED_INT default: { - console.error('Illegal index buffer stride.'); + error('Illegal index buffer stride.'); } } } From 6b42ad24ac0e2c5ff93676cd50073aa8a5225d90 Mon Sep 17 00:00:00 2001 From: Zhou Zhenglong Date: Wed, 19 Jul 2023 11:53:47 +0800 Subject: [PATCH 57/57] fix def --- cocos/gfx/base/define.ts | 3 ++- native/cocos/renderer/gfx-base/GFXDef-common.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index 66ea06c825c..ed23330b928 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -407,7 +407,8 @@ export enum TextureFlagBit { GENERAL_LAYOUT = 0x2, // For inout framebuffer attachments EXTERNAL_OES = 0x4, // External oes texture EXTERNAL_NORMAL = 0x8, // External normal texture - LAZILY_ALLOCATED = 0x10 // Try lazily allocated mode. + MUTABLE_STORAGE = 0x10, // Texture is mutable or not, default is immutable(only for webgl2) + LAZILY_ALLOCATED = 0x20, // Try lazily allocated mode. } export enum FormatFeatureBit { diff --git a/native/cocos/renderer/gfx-base/GFXDef-common.h b/native/cocos/renderer/gfx-base/GFXDef-common.h index b865b7cc9b0..5af6e92cfa2 100644 --- a/native/cocos/renderer/gfx-base/GFXDef-common.h +++ b/native/cocos/renderer/gfx-base/GFXDef-common.h @@ -478,7 +478,8 @@ enum class TextureFlagBit : uint32_t { GENERAL_LAYOUT = 0x2, // @deprecated, For inout framebuffer attachments EXTERNAL_OES = 0x4, // External oes texture EXTERNAL_NORMAL = 0x8, // External normal texture - LAZILY_ALLOCATED = 0x10 // Try lazily allocated mode. + MUTABLE_STORAGE = 0x10, // Texture is mutable or not, default is immutable(only for webgl2) + LAZILY_ALLOCATED = 0x20, // Try lazily allocated mode. }; using TextureFlags = TextureFlagBit; CC_ENUM_BITWISE_OPERATORS(TextureFlagBit);