Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3.8.4 instance buffer #17638

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions cocos/rendering/custom/scene-culling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { RenderQueue, RenderQueueQuery, instancePool } from './web-pipeline-type
import { ObjectPool } from './utils';
import { getUniformBlockSize } from './layout-graph-utils';
import { WebProgramLibrary } from './web-program-library';
import { legacyCC } from '../../core/global-exports';
import type { Director } from '../../game/director';

const vec3Pool = new ObjectPool(() => new Vec3());
class CullingPools {
Expand Down Expand Up @@ -323,7 +325,12 @@ export class SceneCulling {
this.lightBoundsCullings.clear();
this.lightBoundsCullingResults.length = 0;
this.renderQueueIndex.clear();
this.renderQueues.length = 0;
// update render queue frame id
const frameContextID: number = (legacyCC.director as Director).getTotalFrames() % 2;
for (const rq of this.renderQueues) {
rq.setCurrentFrameContextID(frameContextID);
rq.update();
}
this.renderQueueQueryIndex.clear();
this.numLightBoundsCulling = 0;
this.numFrustumCulling = 0;
Expand Down Expand Up @@ -413,8 +420,8 @@ export class SceneCulling {
if (renderQueueID !== undefined) {
const rq = this.renderQueues[renderQueueID];
if (DEBUG) {
assert(rq.camera === camera);
assert((rq.sceneFlags & this.kFilterMask) === (sceneFlags & this.kFilterMask));
assert(rq.camera === camera, 'RenderQueue camera mismatch');
assert((rq.sceneFlags & this.kFilterMask) === (sceneFlags & this.kFilterMask), 'RenderQueue sceneFlags mismatch');
}
rq.sceneFlags |= sceneFlags & this.kDrawMask;
return renderQueueID;
Expand All @@ -425,9 +432,7 @@ export class SceneCulling {
// renderQueues are not cleared, so we can reuse the space
// this->renderQueues.size() is more like a capacity
if (this.numRenderQueues > this.renderQueues.length) {
const renderQueue = this.cullingPools.renderQueueRecycle.add();
renderQueue.update();
this.renderQueues.push(renderQueue);
this.renderQueues.push(new RenderQueue());
}
const rq = this.renderQueues[targetID];

Expand All @@ -436,11 +441,11 @@ export class SceneCulling {

// Update render queue
if (DEBUG) {
assert(rq.empty());
assert(rq.camera === null);
assert(rq.sceneFlags === SceneFlags.NONE);
assert(camera !== null);
assert(this.renderQueueIndex.size === this.numRenderQueues);
assert(rq.empty(), 'RenderQueue is not empty');
assert(rq.camera === null, 'RenderQueue camera is not null');
assert(rq.sceneFlags === SceneFlags.NONE, 'RenderQueue sceneFlags is not 0');
assert(camera !== null, 'Camera is not null');
assert(this.renderQueueIndex.size === this.numRenderQueues, 'RenderQueueIndex size mismatch');
}
rq.camera = camera;
rq.sceneFlags = sceneFlags & this.kAllMask;
Expand Down Expand Up @@ -664,8 +669,8 @@ export class SceneCulling {
// render queue target
const renderQueue = this.renderQueues[targetID];
if (DEBUG) {
assert(targetID < this.renderQueues.length);
assert(renderQueue.empty());
assert(targetID < this.renderQueues.length, `RenderQueue targetID(${targetID}) out of range`);
assert(renderQueue.empty(), 'RenderQueue is not empty');
}

const [frustomCulledResultID, lightBoundsCullingID, phaseLayoutID] = extractRenderQueueKey(key);
Expand Down
34 changes: 30 additions & 4 deletions cocos/rendering/custom/web-pipeline-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DEBUG } from 'internal:constants';
import { Mat4, RecyclePool, IVec4Like, IMat4Like, IVec2Like,
Color as CoreColor, assert, cclegacy, Quat, Vec4, Vec2, Vec3, toRadian } from '../../core';
import { Color, CommandBuffer, DescriptorSet, Buffer, Device, PipelineState, RenderPass, Sampler, Texture, deviceManager } from '../../gfx';
Expand Down Expand Up @@ -903,9 +904,24 @@ export class RenderDrawQueue {
}

export class RenderInstancingQueue {
passInstances: Map<Pass, number> = new Map<Pass, number>();
instanceBuffers: Array<InstancedBuffer> = new Array<InstancedBuffer>();
sortedBatches: Array<InstancedBuffer> = new Array<InstancedBuffer>();
readonly passInstances: Map<Pass, number> = new Map<Pass, number>();
readonly sortedBatches: Array<InstancedBuffer> = new Array<InstancedBuffer>();
readonly instanceBuffersArray: Array<Array<InstancedBuffer>> = new Array<Array<InstancedBuffer>>();
instanceBuffers: Array<InstancedBuffer>;

constructor () {
for (let i = 0; i < 2; ++i) {
this.instanceBuffersArray.push(new Array<InstancedBuffer>());
}
this.instanceBuffers = this.instanceBuffersArray[0];
}

setCurrentFrameContextID (idx: number): void {
if (DEBUG) {
assert(idx < this.instanceBuffersArray.length, 'index out of range');
}
this.instanceBuffers = this.instanceBuffersArray[idx];
}

empty (): boolean {
return this.passInstances.size === 0;
Expand All @@ -923,7 +939,11 @@ export class RenderInstancingQueue {

const instanceBuffer = this.instanceBuffers[instanceBufferID];
instanceBuffer.pass = pass;
const instances = instanceBuffer.instances;
if (DEBUG) {
for (const item of instanceBuffer.instances) {
assert(item.count === 0, `InstancedBuffer is not cleared.`);
}
}
}

const instancedBuffer = this.instanceBuffers[this.passInstances.get(pass)!];
Expand All @@ -933,6 +953,7 @@ export class RenderInstancingQueue {
clear (): void {
this.sortedBatches.length = 0;
this.passInstances.clear();
// InstanceBuffers can be cleared, since only objects on the cpu side are cleared.
const instanceBuffers = this.instanceBuffers;
instanceBuffers.forEach((instance) => {
instance.clear();
Expand Down Expand Up @@ -1065,6 +1086,11 @@ export class RenderQueue {
&& this.transparentInstancingQueue.empty();
}

setCurrentFrameContextID (idx: number): void {
this.opaqueInstancingQueue.setCurrentFrameContextID(idx);
this.transparentInstancingQueue.setCurrentFrameContextID(idx);
}

recordCommands (cmdBuffer: CommandBuffer, renderPass: RenderPass, sceneFlags: SceneFlags): void {
const offsets = this.lightByteOffset === 0xFFFFFFFF ? null : [this.lightByteOffset];
if (sceneFlags & (SceneFlags.OPAQUE | SceneFlags.MASK)) {
Expand Down