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

Reuse webgpu resources #18208

Open
wants to merge 36 commits into
base: v3.8.6
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1af5121
Reuse webgpu layout
GengineJS Jan 14, 2025
f19da2e
ADAPTS the effect of new binding
GengineJS Jan 16, 2025
2ee3be2
update
GengineJS Jan 16, 2025
3d94289
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Jan 16, 2025
3be250f
update
GengineJS Jan 16, 2025
daf906f
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Jan 16, 2025
f2cf144
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Jan 17, 2025
19039cc
New pipeline opening screen
GengineJS Jan 17, 2025
71028c4
update
GengineJS Jan 17, 2025
9c6c01e
add missing info
star-e Jan 17, 2025
381104e
Merge pull request #2 from star-e/v3.8.6-0114-hyde
GengineJS Jan 17, 2025
c905efb
Fixed 2d texture mapping cubemap error
GengineJS Jan 17, 2025
ebc4fe8
update
GengineJS Jan 20, 2025
46fc002
Fix the new pipeline referencing the meaningless globalDsManager object.
GengineJS Jan 20, 2025
47c10eb
change storage image to sampler texture
star-e Jan 20, 2025
f3c21de
Merge pull request #3 from star-e/v3.8.6-0114-cube
GengineJS Jan 20, 2025
6af7930
Merge branch 'v3.8.6-0114' of github.com:GengineJS/engine into v3.8.6…
GengineJS Jan 20, 2025
0227211
Fixed the issue where the testlist was not displayed.
GengineJS Jan 22, 2025
41d7dc4
fixed buffer storage usage warning
GengineJS Feb 7, 2025
464d3ce
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 7, 2025
59dbad8
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 10, 2025
5af5597
fixed storage buffer usage warning
GengineJS Feb 10, 2025
e58edbd
update default storage buffer logic
GengineJS Feb 10, 2025
d2c67e8
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 12, 2025
382fa03
fixed shadowmap
GengineJS Feb 14, 2025
112f3ea
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 14, 2025
b58aad3
fixed texture not copydst
GengineJS Feb 19, 2025
006ca59
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 19, 2025
4fc304e
Fix webgpu import incompatibility problem
GengineJS Feb 20, 2025
b25bc55
Support dynamic import for WebGPU wasm
wdzhangchukong Feb 24, 2025
53c7ddb
Merge pull request #4 from wdzhangchukong/v3.8.6-0114
GengineJS Feb 24, 2025
e75d92f
Fix the problem of dynamic buffer offset error.
GengineJS Feb 25, 2025
60f5d04
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 25, 2025
ba9df78
Merge branch 'v3.8.6-0114' of github.com:GengineJS/engine into v3.8.6…
GengineJS Feb 25, 2025
6fa7f75
update
GengineJS Feb 26, 2025
cc4917f
Merge branch 'v3.8.6' of github.com:cocos/cocos-engine into v3.8.6-0114
GengineJS Feb 26, 2025
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
96 changes: 58 additions & 38 deletions cocos/gfx/webgpu/webgpu-command-buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
Filter,
TextureBlit,
ShaderStageFlagBit,
DescriptorSetInfo,
} from '../base/define';
import { Framebuffer } from '../base/framebuffer';
import { InputAssembler } from '../base/input-assembler';
Expand Down Expand Up @@ -75,6 +76,7 @@ import { WebGPUSwapchain } from './webgpu-swapchain';
import { WebGPUPipelineLayout } from './webgpu-pipeline-layout';
import { WebGPUDescriptorSetLayout } from './webgpu-descriptor-set-layout';
import { error, errorID } from '../../core';
import { SetIndex } from '../../rendering/define';

export interface IWebGPUDepthBias {
constantFactor: number;
Expand All @@ -101,6 +103,7 @@ export interface IWebGPUStencilCompareMask {
interface CommandEncoder { commandEncoder: GPUCommandEncoder, renderPassEncoder: GPURenderPassEncoder }
let currPipelineState: WebGPUPipelineState | null = null;
const descriptorSets: WebGPUDescriptorSet[] = [];
const groupSets: SetIndex[] = [SetIndex.GLOBAL, SetIndex.MATERIAL, SetIndex.LOCAL];
const renderAreas: Rect[] = [];
export class WebGPUCommandBuffer extends CommandBuffer {
public pipelineBarrier (
Expand Down Expand Up @@ -626,34 +629,50 @@ export class WebGPUCommandBuffer extends CommandBuffer {
}
const gpuPipelineLayout = this._curGPUPipelineState.gpuPipelineLayout as IWebGPUGPUPipelineLayout;
const wgpuPipLayout = (currPipelineState?.pipelineLayout as WebGPUPipelineLayout);
let needFetchPipLayout = false;
const descSize = descriptorSets.length;
for (let i = 0; i < descSize; i++) {
descriptorSets[i].prepare(
i ? DescUpdateFrequency.NORMAL : DescUpdateFrequency.LOW,
bindingMaps.get(i)!,
vertBinds[i] || [],
fragBinds[i] || [],
);
const layout = descriptorSets[i].layout as WebGPUDescriptorSetLayout;
const currGrpLayout = layout.gpuDescriptorSetLayout!.bindGroupLayout;
const notEqualLayout = gpuPipelineLayout.gpuBindGroupLayouts[i] !== currGrpLayout;
if (layout.hasChanged || notEqualLayout) {
if (notEqualLayout) {
wgpuPipLayout.changeSetLayout(i, layout);
}
layout.resetChanged();
needFetchPipLayout = true;
// const needFetchPipLayout = false;
// const descSize = descriptorSets.length;
for (let i = 0; i < groupSets.length; i++) {
const currSetIdx = groupSets[i];
const currDesc = descriptorSets[currSetIdx];
if (currDesc) {
currDesc.prepare();
} else {
const currLayout = wgpuPipLayout.setLayouts[currSetIdx];
const currLayoutInfo = new DescriptorSetInfo(currLayout);
const newDescSet = WebGPUDeviceManager.instance.createDescriptorSet(currLayoutInfo) as WebGPUDescriptorSet;
descriptorSets[currSetIdx] = newDescSet;
newDescSet.prepare(true);
// this._curGPUDescriptorSets[currSetIdx] = newDescSet.gpuDescriptorSet;
}
}

if (needFetchPipLayout || !wgpuPipLayout.gpuPipelineLayout!.nativePipelineLayout
|| this._curGPUPipelineState.pipelineState!.layout !== gpuPipelineLayout.nativePipelineLayout) {
wgpuPipLayout.fetchPipelineLayout(false);
this._curWebGPUPipelineState?.updatePipelineLayout();
needFetchPipLayout = true;
}
this._curWebGPUPipelineState!.prepare(this._curGPUInputAssembler!, needFetchPipLayout);
// const layout = descriptorSets[i].layout as WebGPUDescriptorSetLayout;
// const currGrpLayout = layout.gpuDescriptorSetLayout!.bindGroupLayout;
// const notEqualLayout = gpuPipelineLayout.gpuBindGroupLayouts[i] !== currGrpLayout;
// if (layout.hasChanged || notEqualLayout) {
// if (notEqualLayout) {
// wgpuPipLayout.changeSetLayout(i, layout);
// }
// layout.resetChanged();
// needFetchPipLayout = true;
// }
}

// wgpuPipLayout.setLayouts.forEach((layout) => {

// });

// groupSets.forEach((val) => {
// if (!descriptorSets[val]) {
// descriptorSets[val];
// }
// });

// if (needFetchPipLayout || !wgpuPipLayout.gpuPipelineLayout!.nativePipelineLayout
// || this._curGPUPipelineState.pipelineState!.layout !== gpuPipelineLayout.nativePipelineLayout) {
// wgpuPipLayout.fetchPipelineLayout(false);
// this._curWebGPUPipelineState?.updatePipelineLayout();
// needFetchPipLayout = true;
// }
this._curWebGPUPipelineState!.prepare(this._curGPUInputAssembler!);
const { dynamicOffsetIndices } = gpuPipelineLayout;
// ----------------------------wgpu pipline state-----------------------------
const wgpuPipeline = this._curGPUPipelineState.nativePipeline as GPURenderPipeline;
Expand All @@ -668,20 +687,21 @@ export class WebGPUCommandBuffer extends CommandBuffer {
};
this._renderPassFuncQueue.push(stencilRefFunc);
}
const currGPUDescSize = this._curGPUDescriptorSets.length;
const currGPUDescSize = groupSets.length;
const wgpuBindGroups = new Array<GPUBindGroup>(currGPUDescSize);
const wgpuDynOffsets = new Array<number[]>(currGPUDescSize);
for (let i = 0; i < currGPUDescSize; i++) {
const curGpuDesc = this._curGPUDescriptorSets[i];
wgpuBindGroups[i] = curGpuDesc.bindGroup;
wgpuDynOffsets[i] = [...this._curDynamicOffsets[i]];
if (!descriptorSets[i].dynamicOffsetCount) {
wgpuDynOffsets[i] = [];
} else if (descriptorSets[i] && descriptorSets[i].dynamicOffsetCount !== wgpuDynOffsets[i].length) {
wgpuDynOffsets[i].length = descriptorSets[i].dynamicOffsetCount;
for (let j = 0; j < descriptorSets[i].dynamicOffsetCount; j++) {
if (!wgpuDynOffsets[i][j]) {
wgpuDynOffsets[i][j] = 0;
const currSetIdx = groupSets[i];
const curGpuDesc = descriptorSets[currSetIdx].gpuDescriptorSet;
wgpuBindGroups[currSetIdx] = curGpuDesc.bindGroup;
wgpuDynOffsets[currSetIdx] = [...this._curDynamicOffsets[currSetIdx]];
if (!descriptorSets[currSetIdx].dynamicOffsetCount) {
wgpuDynOffsets[currSetIdx] = [];
} else if (descriptorSets[currSetIdx] && descriptorSets[currSetIdx].dynamicOffsetCount !== wgpuDynOffsets[currSetIdx].length) {
wgpuDynOffsets[currSetIdx].length = descriptorSets[currSetIdx].dynamicOffsetCount;
for (let j = 0; j < descriptorSets[currSetIdx].dynamicOffsetCount; j++) {
if (!wgpuDynOffsets[currSetIdx][j]) {
wgpuDynOffsets[currSetIdx][j] = 0;
}
}
}
Expand Down
125 changes: 125 additions & 0 deletions cocos/gfx/webgpu/webgpu-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
formatAlignment,
alignTo,
TextureFlagBit,
DescriptorSetLayoutBinding,
} from '../base/define';

import { WebGPUCommandAllocator } from './webgpu-command-allocator';
Expand Down Expand Up @@ -1371,6 +1372,123 @@ export function WebGPUCmdFuncCopyTexImagesToTexture (
}
}

const GFXSampleTypeToGPUTextureSampleType: GPUTextureSampleType[] = [
'float',
'unfilterable-float',
'sint',
'uint',
];

const GFXViewDimensionToGPUViewDimension: GPUTextureViewDimension[] = [
'2d',
'2d',
'1d',
'1d',
'2d',
'2d-array',
'2d',
'2d-array',
'3d',
'cube',
'cube-array',
'2d',
];

const GFXMemoryAccessToGPUStorageTextureAccess: (GPUStorageTextureAccess | undefined)[] = [
'read-only',
'read-only',
'write-only',
'read-write',
];

export function CreateBindGroupLayoutEntry (currBind: DescriptorSetLayoutBinding): GPUBindGroupLayoutEntry[] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the same coding style, the first letter of functions must use lowercase .

const binding = currBind.binding;
// Define the mapping from ShaderStageFlagBit to GPUShaderStage
const gpuVisibility = GFXStageToWebGPUStage(currBind.stageFlags);
const entrys: GPUBindGroupLayoutEntry[] = [];
const entry: GPUBindGroupLayoutEntry = {
binding,
visibility: gpuVisibility,
};
entrys.push(entry);
let entrySampler: GPUBindGroupLayoutEntry | null = null;
const samplerType = GFXSampleTypeToGPUTextureSampleType[currBind.sampleType];
const isTexUnFilter = samplerType === 'unfilterable-float';
const viewDimension = GFXViewDimensionToGPUViewDimension[currBind.viewDimension];
const type = currBind.descriptorType;
const multisampled = currBind.viewDimension > 5 && currBind.viewDimension < 8;
switch (type) {
case DescriptorType.UNIFORM_BUFFER:
case DescriptorType.DYNAMIC_UNIFORM_BUFFER:
entry.buffer = {
type: 'uniform',
hasDynamicOffset: type === DescriptorType.DYNAMIC_UNIFORM_BUFFER,
minBindingSize: undefined,
};
break;

case DescriptorType.STORAGE_BUFFER:
case DescriptorType.DYNAMIC_STORAGE_BUFFER:
entry.buffer = {
type: 'storage',
hasDynamicOffset: type === DescriptorType.DYNAMIC_STORAGE_BUFFER,
minBindingSize: undefined,
};
break;

case DescriptorType.SAMPLER_TEXTURE:
// Assuming this is a combined image sampler
entry.texture = {
sampleType: samplerType, // or 'unfilterable-float', 'depth', 'sint', 'uint'
viewDimension, // or 'cube', '3d', '1d'
multisampled,
};
entrySampler = {
binding: binding + SEPARATE_SAMPLER_BINDING_OFFSET,
visibility: gpuVisibility,
};
entrySampler.sampler = {
type: isTexUnFilter ? 'non-filtering' : 'filtering', // or 'non-filtering', 'comparison'
};
entrys.push(entrySampler);
break;

case DescriptorType.SAMPLER:
entry.sampler = {
type: isTexUnFilter ? 'non-filtering' : 'filtering', // or 'non-filtering', 'comparison'
};
break;

case DescriptorType.TEXTURE:
entry.texture = {
sampleType: samplerType, // or 'unfilterable-float', 'depth', 'sint', 'uint'
viewDimension, // or 'cube', '3d', '1d'
multisampled,
};
break;

case DescriptorType.STORAGE_IMAGE:
entry.storageTexture = {
access: GFXMemoryAccessToGPUStorageTextureAccess[currBind.access], // or 'read-only', 'read-write'
format: GFXFormatToWGPUFormat(currBind.format), // Choose the appropriate texture format
viewDimension, // or 'cube', '3d', '1d'
};
break;

case DescriptorType.INPUT_ATTACHMENT:
entry.texture = {
sampleType: samplerType, // or 'unfilterable-float', 'depth', 'sint', 'uint'
viewDimension, // or 'cube', '3d', '1d'
multisampled,
};
break;

default:
throw new Error(`Unsupported descriptor type: ${type}`);
}
return entrys;
}

export function TextureSampleTypeTrait (format: Format): GPUTextureSampleType {
// See https://gpuweb.github.io/gpuweb/#texture-format-caps
switch (format) {
Expand Down Expand Up @@ -1420,6 +1538,13 @@ export function TextureSampleTypeTrait (format: Format): GPUTextureSampleType {
}
}

export function FormatToWGPUFormatType (format: Format): GPUTextureSampleType {
if (format === Format.DEPTH_STENCIL) {
return 'unfilterable-float';
}
return TextureSampleTypeTrait(format);
}

interface MipmapPassData {
vertShader: GPUShaderModule;
fragShader: GPUShaderModule;
Expand Down
2 changes: 1 addition & 1 deletion cocos/gfx/webgpu/webgpu-define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/

import { WEBGPU } from 'internal:constants';
import { gfx, webgpuAdapter, glslangWasmModule, promiseForWebGPUInstantiation, spirvOptModule, twgslModule } from '../../webgpu/instantiated';
import { gfx, webgpuAdapter, glslangWasmModule, promiseForWebGPUInstantiation, twgslModule } from '../../webgpu/instantiated';
import {
Texture, CommandBuffer, DescriptorSet, Device, InputAssembler, Buffer, Shader
} from './override';
Expand Down
Loading
Loading