Skip to content

Commit

Permalink
Optimize the depthattachment of renderpass and fix the webgpu sampler…
Browse files Browse the repository at this point in the history
… type error and fix the problem that webgpu post-processing does not work
  • Loading branch information
GengineJS committed Jul 9, 2024
1 parent 2f1ab9d commit c1ada20
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 34 deletions.
10 changes: 6 additions & 4 deletions cocos/gfx/base/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1631,16 +1631,18 @@ export class RenderPassInfo {

constructor (
public colorAttachments: ColorAttachment[] = [],
public depthStencilAttachment: DepthStencilAttachment = new DepthStencilAttachment(),
public depthStencilResolveAttachment: DepthStencilAttachment = new DepthStencilAttachment(),
public depthStencilAttachment: DepthStencilAttachment | null = null,
public depthStencilResolveAttachment: DepthStencilAttachment | null = null,
public subpasses: SubpassInfo[] = [],
public dependencies: SubpassDependency[] = [],
) {}

public copy (info: Readonly<RenderPassInfo>): RenderPassInfo {
deepCopy(this.colorAttachments, info.colorAttachments, ColorAttachment);
this.depthStencilAttachment.copy(info.depthStencilAttachment);
this.depthStencilResolveAttachment.copy(info.depthStencilResolveAttachment);
if (info.depthStencilAttachment && this.depthStencilAttachment) this.depthStencilAttachment.copy(info.depthStencilAttachment);
if (info.depthStencilResolveAttachment && this.depthStencilResolveAttachment) {
this.depthStencilResolveAttachment.copy(info.depthStencilResolveAttachment);
}
deepCopy(this.subpasses, info.subpasses, SubpassInfo);
deepCopy(this.dependencies, info.dependencies, SubpassDependency);
return this;
Expand Down
5 changes: 4 additions & 1 deletion cocos/gfx/webgpu/webgpu-descriptor-set-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
DescriptorSetLayoutBinding,
Format,
DescriptorType,
Filter,
} from '../base/define';
import { DescUpdateFrequency, WebGPUDeviceManager, isBound } from './define';
import { WebGPUTexture } from './webgpu-texture';
Expand Down Expand Up @@ -150,7 +151,9 @@ export class WebGPUDescriptorSetLayout extends DescriptorSetLayout {
entries.set(bindIdx, currEntry);
}
if (sampler) {
currEntry.sampler = { type: GFXSamplerToGPUSamplerDescType(sampler.info) };
const currTex = entries.get(bindIdx - SEPARATE_SAMPLER_BINDING_OFFSET)!;
const isUnFilter = currTex.texture!.sampleType === 'unfilterable-float';
currEntry.sampler = { type: isUnFilter ? 'non-filtering' : GFXSamplerToGPUSamplerDescType(sampler.info) };
// const defaultSampler = wgpuDeviceInst.getDefaultDescResources(currEntry, sampler.gpuSampler) as WebGPUSampler;
// this.samplers.set(bindIdx, defaultSampler);
entries.set(bindIdx, currEntry);
Expand Down
14 changes: 12 additions & 2 deletions cocos/gfx/webgpu/webgpu-descriptor-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
DescriptorSetLayoutBinding,
DescriptorType,
ShaderStageFlagBit,
Filter,
} from '../base/define';
import { DescUpdateFrequency, WebGPUDeviceManager, isBound } from './define';
import { SEPARATE_SAMPLER_BINDING_OFFSET } from './webgpu-commands';
Expand Down Expand Up @@ -133,10 +134,19 @@ export class WebGPUDescriptorSet extends DescriptorSet {
const samplerIdx = bind.binding + SEPARATE_SAMPLER_BINDING_OFFSET;
this._gpuDescriptorSet!.gpuDescriptors[bind.binding].gpuSampler = sampler.gpuSampler;
const layout = this._layout as WebGPUDescriptorSetLayout;
sampler.createGPUSampler(this._textures[bind.binding].levelCount);
const currTexture = this._textures[bind.binding] as WebGPUTexture;
const levelCount = currTexture.levelCount;
const texFormat = currTexture.format;
const isUnFilter = FormatToWGPUFormatType(texFormat) === 'unfilterable-float';
if (isUnFilter) {
sampler.gpuSampler.minFilter = Filter.POINT;
sampler.gpuSampler.magFilter = Filter.POINT;
sampler.gpuSampler.mipFilter = Filter.POINT;
}
const currGPUSampler = sampler.createGPUSampler(levelCount);
const bindSamplerGrpEntry: GPUBindGroupEntry = {
binding: samplerIdx,
resource: sampler.gpuSampler?.gpuSampler as GPUSampler,
resource: currGPUSampler as GPUSampler,
};
layout.updateBindGroupLayout(bind, null, null, sampler);
this._bindGroupEntries.set(samplerIdx, bindSamplerGrpEntry);
Expand Down
39 changes: 33 additions & 6 deletions cocos/gfx/webgpu/webgpu-sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ import { IWebGPUGPUSampler } from './webgpu-gpu-objects';
import { SamplerInfo } from '../base/define';
import { WebGPUDeviceManager } from './define';

const samplerCaches: Map<number, GPUSampler> = new Map();

export class WebGPUSampler extends Sampler {
public get gpuSampler (): IWebGPUGPUSampler {
return this._gpuSampler!;
}

public get samplerInfo (): SamplerInfo {
return this._info;
}

private _gpuSampler: IWebGPUGPUSampler | null = null;
private _hasChange: boolean = false;
get hasChange (): boolean {
Expand Down Expand Up @@ -64,13 +70,34 @@ export class WebGPUSampler extends Sampler {
};
}

public createGPUSampler (mipLevel: number = 1): void {
if (this._gpuSampler && !this.gpuSampler.gpuSampler) {
this._gpuSampler.mipLevel = mipLevel;
const device = WebGPUDeviceManager.instance;
this._hasChange = true;
WebGPUCmdFuncCreateSampler(device, this._gpuSampler);
private _computeHash (info: IWebGPUGPUSampler): number {
let hash = info.minFilter;
hash |= ((info.magFilter as number) << 2);
hash |= ((info.mipFilter as number) << 4);
hash |= ((info.addressU as number) << 6);
hash |= ((info.addressV as number) << 8);
hash |= ((info.addressW as number) << 10);
hash |= (info.maxAnisotropy << 12);
hash |= ((info.compare as number) << 16);
hash |= ((info.mipLevel) << 18);
return hash;
}

public createGPUSampler (mipLevel: number = 1): GPUSampler | null {
if (!this._gpuSampler) {
return null;
}
this._gpuSampler.mipLevel = mipLevel;
const currHash = this._computeHash(this._gpuSampler);
let currGPUSampler = samplerCaches.get(currHash);
if (currGPUSampler) return currGPUSampler;

const device = WebGPUDeviceManager.instance;
this._hasChange = true;
WebGPUCmdFuncCreateSampler(device, this._gpuSampler);
currGPUSampler = this._gpuSampler.gpuSampler!;
samplerCaches.set(currHash, currGPUSampler);
return currGPUSampler;
}

public destroy (): void {
Expand Down
13 changes: 5 additions & 8 deletions cocos/rendering/custom/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,11 +825,6 @@ class DeviceRenderPass implements RecordingInterface {
this._passID = cclegacy.rendering.getPassID(this._layoutName);
const depthStencilAttachment = new DepthStencilAttachment();
depthStencilAttachment.format = Format.DEPTH_STENCIL;
depthStencilAttachment.depthLoadOp = LoadOp.DISCARD;
depthStencilAttachment.stencilLoadOp = LoadOp.DISCARD;
depthStencilAttachment.stencilStoreOp = StoreOp.DISCARD;
depthStencilAttachment.depthStoreOp = StoreOp.DISCARD;

const colors: ColorAttachment[] = [];
const colorTexs: Texture[] = [];
let depthTex: Texture | null = null;
Expand Down Expand Up @@ -907,11 +902,13 @@ class DeviceRenderPass implements RecordingInterface {
const currTex = device.createTexture(new TextureInfo());
colorTexs.push(currTex);
}
const renderPassInfo = new RenderPassInfo();
renderPassInfo.colorAttachments = colors;
const depth = swapchain ? swapchain.depthStencilTexture : depthTex;
if (!depth) {
depthStencilAttachment.format = Format.DEPTH_STENCIL;
if (depth) {
renderPassInfo.depthStencilAttachment = depthStencilAttachment;
}
this._renderPass = device.createRenderPass(new RenderPassInfo(colors, depthStencilAttachment));
this._renderPass = device.createRenderPass(renderPassInfo);
this._framebuffer = framebuffer || device.createFramebuffer(new FramebufferInfo(
this._renderPass,
swapchain ? [swapchain.colorTexture] : colorTexs,
Expand Down
12 changes: 6 additions & 6 deletions cocos/rendering/pipeline-ubo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,12 @@ export class PipelineUBO {
protected declare _pipeline: PipelineRuntime;

/**
*|combinedSignY|clipSpaceSignY|screenSpaceSignY| Backends |
*| :--: | :--: | :--: | :--: |
*| 0 | -1 | -1 | Vulkan |
*| 1 | 1 | -1 | Metal |
*| 2 | -1 | 1 | |
*| 3 | 1 | 1 | GL-like |
*|combinedSignY|clipSpaceSignY|screenSpaceSignY| Backends |
*| :--: | :--: | :--: | :--: |
*| 0 | -1 | -1 | Vulkan |
*| 1 | 1 | -1 |Metal/WebGPU|
*| 2 | -1 | 1 | |
*| 3 | 1 | 1 | GL-like |
*/
public static getCombineSignY (): number {
return PipelineUBO._combineSignY;
Expand Down
25 changes: 21 additions & 4 deletions editor/assets/default_renderpipeline/builtin-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ class PipelineConfigs {
platform = new Vec4(0, 0, 0, 0);
}

function isWebGPU() {
return (cclegacy.WebGPUDevice && cclegacy.director.root.device instanceof cclegacy.WebGPUDevice);
}

function setupPipelineConfigs(
ppl: rendering.BasicPipeline,
configs: PipelineConfigs,
Expand All @@ -114,7 +118,8 @@ function setupPipelineConfigs(

const device = ppl.device;
configs.platform.x = configs.isMobile ? 1.0 : 0.0;
configs.platform.w = (device.capabilities.screenSpaceSignY * 0.5 + 0.5) << 1 | (device.capabilities.clipSpaceSignY * 0.5 + 0.5);
const screenSpaceSignY = device.capabilities.screenSpaceSignY;
configs.platform.w = (screenSpaceSignY * 0.5 + 0.5) << 1 | (device.capabilities.clipSpaceSignY * 0.5 + 0.5);
}

const defaultSettings = makePipelineSettings();
Expand Down Expand Up @@ -797,6 +802,10 @@ if (rendering) {
this._viewport.width = width;
this._viewport.height = height;

// if (cclegacy.WebGPUDevice && ppl.device instanceof cclegacy.WebGPUDevice) {
// width = 512;
// height = 512;
// }
// ----------------------------------------------------------------
// CSM Shadow Map
// ----------------------------------------------------------------
Expand All @@ -810,7 +819,7 @@ if (rendering) {
for (let level = 0; level !== csmLevel; ++level) {
getCsmMainLightViewport(light, width, height, level, this._viewport, this._configs.screenSpaceSignY);
const queue = pass.addQueue(QueueHint.NONE, 'shadow-caster');
queue.setViewport(this._viewport);
isWebGPU() || queue.setViewport(this._viewport);
queue
.addScene(camera, SceneFlags.OPAQUE | SceneFlags.MASK | SceneFlags.SHADOW_CASTER)
.useLightFrustum(light, level);
Expand Down Expand Up @@ -1219,7 +1228,7 @@ if (rendering) {
colorName, depthStencilName, depthStencilStoreOp)
: this._addForwardMultipleRadiancePasses(ppl, id, camera, width, height, mainLight,
colorName, depthStencilName, depthStencilStoreOp);

this.addPlanarShadowQueues(ppl, pass, camera, mainLight);
// ----------------------------------------------------------------
// Forward Lighting (Blend)
// ----------------------------------------------------------------
Expand Down Expand Up @@ -1281,7 +1290,15 @@ if (rendering) {

return pass;
}

public addPlanarShadowQueues(ppl: rendering.BasicPipeline, pass: rendering.BasicRenderPassBuilder,
camera: renderer.scene.Camera, mainLight: renderer.scene.DirectionalLight | null) {
pass.addQueue(QueueHint.BLEND, 'planar-shadow')
.addScene(
camera,
SceneFlags.SHADOW_CASTER | SceneFlags.PLANAR_SHADOW | SceneFlags.BLEND,
mainLight
);
}
private _addForwardMultipleRadiancePasses(
ppl: rendering.BasicPipeline,
id: number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ uniform Pipeline {
// Vulkan 1.0, Flip NDC Y
#pragma define FLIP_VULKAN_NDC(vec) (vec).y = g_platform.w == 0.0 ? -(vec).y : (vec).y

// Metal, Sample from RT
#pragma define FLIP_SAMPLE_FROM_RT(vec) (vec).y = g_platform.w == 1.0 ? 1.0-(vec).y : (vec).y
// GL_Like, Sample from RT
#pragma define FLIP_SAMPLE_FROM_RT(vec) (vec).y = (g_platform.w > 1.0 ? 1.0-(vec).y : (vec).y)
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ CCProgram vs-tonemap %{
FLIP_VULKAN_NDC(In.position);
gl_Position = In.position;
v_uv = a_texCoord;
FLIP_SAMPLE_FROM_RT(v_uv);
}
}%

Expand Down

0 comments on commit c1ada20

Please sign in to comment.