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

[Optimized] upload buffer #17595

Merged
merged 2 commits into from
Sep 3, 2024
Merged
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
65 changes: 37 additions & 28 deletions cocos/rendering/custom/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,17 @@ export function getDescBindingFromName (bindingName: string): number {
return -1;
}

const uniformMap: Map<Buffer, Float32Array> = new Map();
class DescBuffManager {
private buffers: Buffer[] = [];
private currBuffIdx: number = 0;
private device: Device;
public currUniform: Float32Array;
private _root;
constructor (bufferSize: number, numBuffers: number = 2) {
const root = cclegacy.director.root;
const root = this._root = cclegacy.director.root;
const device = root.device;
this.device = device;
this.currUniform = new Float32Array(bufferSize / 4);
for (let i = 0; i < numBuffers; i++) {
const bufferInfo: BufferInfo = new BufferInfo(
BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST,
Expand All @@ -468,36 +470,33 @@ class DescBuffManager {
}
}
getCurrentBuffer (): Buffer {
const root = cclegacy.director.root;
this.currBuffIdx = root.frameCount % this.buffers.length;
this.currBuffIdx = this._root.frameCount % this.buffers.length;
return this.buffers[this.currBuffIdx];
}
updateBuffer (bindId: number, vals: number[], layout: string, setData: DescriptorSetData): void {
updateData (vals: number[]): void {
this.currUniform.set(vals);
}
updateBuffer (bindId: number, setData: DescriptorSetData): void {
const descriptorSet = setData.descriptorSet!;
const buffer = this.getCurrentBuffer();
let currUniform = uniformMap.get(buffer);
if (!currUniform) {
currUniform = new Float32Array(vals);
uniformMap.set(buffer, currUniform);
}
currUniform.set(vals);
buffer.update(currUniform);
buffer.update(this.currUniform);
bindGlobalDesc(descriptorSet, bindId, buffer);
}
}

const buffsMap: Map<string, DescBuffManager> = new Map();

function updateGlobalDescBuffer (blockId: number, sceneId: number, vals: number[], layout: string, setData: DescriptorSetData): void {
const currBindBuffs: Map<string, number> = new Map();
function updateGlobalDescBuffer (blockId: number, sceneId: number, idxRD: number, vals: number[], setData: DescriptorSetData): void {
const bindId = getDescBinding(blockId, setData);
if (bindId === -1) { return; }
const descKey = `${blockId}${bindId}${sceneId}`;
const descKey = `${blockId}${bindId}${idxRD}${sceneId}`;
currBindBuffs.set(descKey, bindId);
let currDescBuff = buffsMap.get(descKey);
if (!currDescBuff) {
buffsMap.set(descKey, new DescBuffManager(vals.length * 4));
buffsMap.set(descKey, new DescBuffManager(vals.length * 4, 2));
currDescBuff = buffsMap.get(descKey);
}
currDescBuff!.updateBuffer(bindId, vals, layout, setData);
currDescBuff!.updateData(vals);
}

const layouts: Map<string, DescriptorSetData> = new Map();
Expand All @@ -522,8 +521,8 @@ export function getDescriptorSetDataFromLayoutId (id: number): DescriptorSetData
return layoutData;
}

export function updateGlobalDescBinding (data: RenderData, sceneId: number, layoutName = 'default'): void {
updatePerPassUBO(layoutName, sceneId, data);
export function updateGlobalDescBinding (data: RenderData, sceneId: number, idxRD: number, layoutName = 'default'): void {
updatePerPassUBO(layoutName, sceneId, idxRD, data);
}

function getUniformBlock (block: string, layoutName: string): UniformBlock | undefined {
Expand Down Expand Up @@ -557,15 +556,20 @@ class ConstantBlockInfo {
blockId: number = -1;
}
const constantBlockMap: Map<number, ConstantBlockInfo> = new Map();
function copyToConstantBuffer (target: number[], val: number[], offset: number): void {
function copyToConstantBuffer (target: number[], val: number[], offset: number): boolean {
let isImparity = false;
if (offset < 0 || offset > target.length) {
throw new Error('Offset is out of the bounds of the target array.');
return isImparity;
}
const length = Math.min(val.length, target.length - offset);

for (let i = 0; i < length; i++) {
target[offset + i] = val[i];
if (target[offset + i] !== val[i]) {
target[offset + i] = val[i];
isImparity = true;
}
}
return isImparity;
}

function addConstantBuffer (block: string, layout: string): number[] | null {
Expand All @@ -587,14 +591,15 @@ function addConstantBuffer (block: string, layout: string): number[] | null {
uniformBlockMap.set(block, buffers);
return buffers;
}
export function updatePerPassUBO (layout: string, sceneId: number, user: RenderData): void {
export function updatePerPassUBO (layout: string, sceneId: number, idxRD: number, user: RenderData): void {
const constantMap = user.constants;
const samplers = user.samplers;
const textures = user.textures;
const buffers = user.buffers;
const webPip = cclegacy.director.root.pipeline as WebPipeline;
const lg = webPip.layoutGraph;
const descriptorSetData = getDescriptorSetDataFromLayout(layout)!;
currBindBuffs.clear();
for (const [key, data] of constantMap) {
let constantBlock = constantBlockMap.get(key);
if (!constantBlock) {
Expand All @@ -607,20 +612,20 @@ export function updatePerPassUBO (layout: string, sceneId: number, user: RenderD
if (offset === -1) {
// Although the current uniformMem does not belong to the current uniform block,
// it does not mean that it should not be bound to the corresponding descriptor.
updateGlobalDescBuffer(blockId, sceneId, constantBuff, layout, descriptorSetData);
updateGlobalDescBuffer(blockId, sceneId, idxRD, constantBuff, descriptorSetData);
continue;
}
constantBlockMap.set(key, new ConstantBlockInfo());
constantBlock = constantBlockMap.get(key)!;
constantBlock.buffer = constantBuff;
constantBlock.blockId = blockId;
constantBlock.offset = offset;
copyToConstantBuffer(constantBuff, data, offset);
updateGlobalDescBuffer(blockId, sceneId, constantBuff, layout, descriptorSetData);
const isImparity = copyToConstantBuffer(constantBuff, data, offset);
if (isImparity) updateGlobalDescBuffer(blockId, sceneId, idxRD, constantBuff, descriptorSetData);
}
} else {
copyToConstantBuffer(constantBlock.buffer, data, constantBlock.offset);
updateGlobalDescBuffer(constantBlock.blockId, sceneId, constantBlock.buffer, layout, descriptorSetData);
const isImparity = copyToConstantBuffer(constantBlock.buffer, data, constantBlock.offset);
if (isImparity) updateGlobalDescBuffer(constantBlock.blockId, sceneId, idxRD, constantBlock.buffer, descriptorSetData);
}
}

Expand All @@ -643,6 +648,10 @@ export function updatePerPassUBO (layout: string, sceneId: number, user: RenderD
bindGlobalDesc(descriptorSet, bindId, value);
}
}
for (const [key, value] of currBindBuffs) {
const buffManager = buffsMap.get(key)!;
buffManager.updateBuffer(value, descriptorSetData);
}
for (const [key, value] of buffers) {
const bindId = getDescBinding(key, descriptorSetData);
if (bindId === -1) { continue; }
Expand Down
11 changes: 9 additions & 2 deletions cocos/rendering/custom/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ class DeviceRenderPass implements RecordingInterface {
protected _viewport: Viewport | null = null;
private _rasterInfo: RasterPassInfo;
private _layout: RenderPassLayoutInfo | null = null;
private _idxOfRenderData: number = 0;
constructor (passInfo: RasterPassInfo) {
this._rasterInfo = passInfo;
const device = context.device;
Expand Down Expand Up @@ -909,6 +910,7 @@ class DeviceRenderPass implements RecordingInterface {
swapchain ? swapchain.depthStencilTexture : depthTex,
));
}
get indexOfRD (): number { return this._idxOfRenderData; }
get layoutName (): string { return this._layoutName; }
get passID (): number { return this._passID; }
get renderLayout (): RenderPassLayoutInfo | null { return this._layout; }
Expand All @@ -920,6 +922,9 @@ class DeviceRenderPass implements RecordingInterface {
get deviceQueues (): Map<number, DeviceRenderQueue> { return this._deviceQueues; }
get rasterPassInfo (): RasterPassInfo { return this._rasterInfo; }
get viewport (): Viewport | null { return this._viewport; }
addIdxOfRD (): void {
this._idxOfRenderData++;
}
visitResource (resName: string): void {
const resourceGraph = context.resourceGraph;
const vertId = resourceGraph.vertex(resName);
Expand Down Expand Up @@ -1040,6 +1045,7 @@ class DeviceRenderPass implements RecordingInterface {
this._layoutName = context.renderGraph.getLayout(id);
this._passID = cclegacy.rendering.getPassID(this._layoutName);
this._deviceQueues.clear();
this._idxOfRenderData = 0;
let framebuffer: Framebuffer | null = null;
const colTextures: Texture[] = [];
const currFramebuffer = this._framebuffer;
Expand Down Expand Up @@ -1234,7 +1240,7 @@ class DeviceComputePass implements RecordingInterface {
queue.record();
}
const renderData = context.renderGraph.getData(this._computeInfo.id);
updateGlobalDescBinding(renderData, -1, context.renderGraph.getLayout(this._computeInfo.id));
updateGlobalDescBinding(renderData, -1, 0, context.renderGraph.getLayout(this._computeInfo.id));
}

resetResource (id: number, pass: ComputePass): void {
Expand Down Expand Up @@ -1392,7 +1398,8 @@ class DeviceRenderScene implements RecordingInterface {

protected _updateGlobal (data: RenderData, sceneId: number): void {
const devicePass = this._currentQueue.devicePass;
updateGlobalDescBinding(data, sceneId, context.renderGraph.getLayout(devicePass.rasterPassInfo.id));
devicePass.addIdxOfRD();
updateGlobalDescBinding(data, sceneId, devicePass.indexOfRD, context.renderGraph.getLayout(devicePass.rasterPassInfo.id));
}

protected _updateRenderData (): void {
Expand Down
Loading