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 #17668

Merged
merged 21 commits into from
Sep 26, 2024
Merged

V3.8.4 #17668

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
67b8d4b
rename event name to fix event name conflict with NodeEventType.MOUSE…
minggo Aug 23, 2024
582e03a
Fix the issue where the cached animationCache object is using a relea…
bofeng-song Aug 27, 2024
9a4693e
Fix the issue where post-processing modifications after rendering are…
GengineJS Aug 29, 2024
6fe9ff7
fix reflection probe bake and planar reflection error in editor (#17584)
star-e Aug 29, 2024
3ad291a
[Optimized] upload buffer (#17595)
GengineJS Sep 3, 2024
a900c7c
update i18n for render pipeline (#17596)
yanOO1497 Sep 3, 2024
3a5898d
revert changes during pipeline replacing (#17597)
star-e Sep 3, 2024
93f859f
Fix custom-pipeline-post-process enable failures (#17601)
knoxHuang Sep 4, 2024
ef76162
Fix the issue where the "Custom" pipeline cannot use post-processing …
GengineJS Sep 4, 2024
b990d85
Fix memory hike caused by repeatedly switching inspectors (#17605)
knoxHuang Sep 5, 2024
78a5f2f
docs: fix spelling issues (#17564)
nnsW3 Sep 6, 2024
3ecad78
Streamline the new pipeline execution code (#17614)
GengineJS Sep 10, 2024
09cada9
Optimize scene culling code (#17619)
GengineJS Sep 10, 2024
d446e3f
Merge render queue (#17622)
star-e Sep 11, 2024
6434f14
Fix the issue where the custom pipeline's RenderTexture output is inc…
GengineJS Sep 12, 2024
90ff207
Merge render queue (Web). (#17628)
star-e Sep 13, 2024
fe616ca
Fix a compilation error on xcode 16.0 (#17645)
dumganhar Sep 18, 2024
82594e9
fix iOS14 batcher2d performance issue (#17646)
star-e Sep 19, 2024
38e303e
optimized code (#17651)
GengineJS Sep 19, 2024
684974d
Fix the incorrect usage of the closure variable 'this' (#17650)
bofeng-song Sep 19, 2024
5ea5825
fix ui per-pass descriptor set (#17663)
star-e Sep 24, 2024
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
10 changes: 9 additions & 1 deletion cocos/gfx/webgl/webgl-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

import { BYTEDANCE } from 'internal:constants';
import { systemInfo } from 'pal/system-info';
import { debugID, error, errorID, CachedArray, cclegacy, assertID } from '../../core';
import { WebGLCommandAllocator } from './webgl-command-allocator';
import { WebGLEXT } from './webgl-define';
Expand All @@ -39,6 +40,7 @@ import {
TextureBlit, Filter,
} from '../base/define';
import { WebGLStateCache } from './webgl-state-cache';
import { OS } from '../../../pal/system-info/enum-type';

export function GFXFormatToWebGLType (format: Format, gl: WebGLRenderingContext): GLenum {
switch (format) {
Expand Down Expand Up @@ -830,7 +832,13 @@ export function WebGLCmdFuncUpdateBuffer (
}
}

if (size === buff.byteLength) {
if (systemInfo.os === OS.IOS && (gpuBuffer.memUsage & MemoryUsageBit.HOST) && offset === 0 && size === buff.byteLength) {
// Fix performance issue on iOS.
// TODO(zhouzhenglong): glBufferSubData is faster than glBufferData in most cases.
// We should use multiple buffers to avoid stall (cpu write conflicts with gpu read).
// Before that, we will use glBufferData instead of glBufferSubData.
gl.bufferData(gpuBuffer.glTarget, buff, gl.DYNAMIC_DRAW);
} else if (size === buff.byteLength) {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff);
} else {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size));
Expand Down
26 changes: 23 additions & 3 deletions cocos/gfx/webgl2/webgl2-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
THE SOFTWARE.
*/

import { systemInfo } from 'pal/system-info';
import {
BufferUsageBit, ColorMask, CullMode, DynamicStateFlagBit, Filter, Format, TextureType, Type, FormatInfo,
FormatInfos, FormatSize, LoadOp, MemoryUsageBit, SampleCount, ShaderStageFlagBit, TextureFlagBit,
Expand All @@ -47,6 +48,7 @@ import {
IWebGL2GPURenderPass,
} from './webgl2-gpu-objects';
import { CachedArray, error, errorID, cclegacy, assertID, debugID } from '../../core';
import { OS } from '../../../pal/system-info/enum-type';

const WebGLWraps: GLenum[] = [
0x2901, // WebGLRenderingContext.REPEAT
Expand Down Expand Up @@ -1001,7 +1003,13 @@ export function WebGL2CmdFuncUpdateBuffer (
cache.glArrayBuffer = gpuBuffer.glBuffer;
}

if (size === buff.byteLength) {
if (systemInfo.os === OS.IOS && (gpuBuffer.memUsage & MemoryUsageBit.HOST) && offset === 0 && size === buff.byteLength) {
// Fix performance issue on iOS.
// TODO(zhouzhenglong): glBufferSubData is faster than glBufferData in most cases.
// We should use multiple buffers to avoid stall (cpu write conflicts with gpu read).
// Before that, we will use glBufferData instead of glBufferSubData.
gl.bufferData(gpuBuffer.glTarget, buff, gl.DYNAMIC_DRAW);
} else if (size === buff.byteLength) {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff);
} else {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size));
Expand All @@ -1022,7 +1030,13 @@ export function WebGL2CmdFuncUpdateBuffer (
cache.glElementArrayBuffer = gpuBuffer.glBuffer;
}

if (size === buff.byteLength) {
if (systemInfo.os === OS.IOS && (gpuBuffer.memUsage & MemoryUsageBit.HOST) && offset === 0 && size === buff.byteLength) {
// Fix performance issue on iOS.
// TODO(zhouzhenglong): glBufferSubData is faster than glBufferData in most cases.
// We should use multiple buffers to avoid stall (cpu write conflicts with gpu read).
// Before that, we will use glBufferData instead of glBufferSubData.
gl.bufferData(gpuBuffer.glTarget, buff, gl.DYNAMIC_DRAW);
} else if (size === buff.byteLength) {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff);
} else {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff.slice(0, size));
Expand All @@ -1035,7 +1049,13 @@ export function WebGL2CmdFuncUpdateBuffer (
cache.glUniformBuffer = gpuBuffer.glBuffer;
}

if (size === buff.byteLength) {
if (systemInfo.os === OS.IOS && (gpuBuffer.memUsage & MemoryUsageBit.HOST) && offset === 0 && size === buff.byteLength) {
// Fix performance issue on iOS.
// TODO(zhouzhenglong): glBufferSubData is faster than glBufferData in most cases.
// We should use multiple buffers to avoid stall (cpu write conflicts with gpu read).
// Before that, we will use glBufferData instead of glBufferSubData.
gl.bufferData(gpuBuffer.glTarget, buff, gl.DYNAMIC_DRAW);
} else if (size === buff.byteLength) {
gl.bufferSubData(gpuBuffer.glTarget, offset, buff);
} else {
gl.bufferSubData(gpuBuffer.glTarget, offset, new Float32Array(buff, 0, size / 4));
Expand Down
4 changes: 2 additions & 2 deletions cocos/input/types/event-enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,14 @@ export enum InputEventType {
* trigger this event.
* @zh 当鼠标离开窗口或者 canvas 时发出该消息。只有 Windows、macOS 或者 PC web 会触发该事件。
*/
MOUSE_LEAVE = 'mouse-leave',
MOUSE_LEAVE = 'mouse-leave-window',

/**
* @en The event type indicates mouse enters the window or canvas. Only Windows, macOS or web PC can
* trigger this event.
* @zh 当鼠标进入窗口或者 canvas 时发出该消息。只有 Windows、macOS 或者 PC web 会触发该事件。
*/
MOUSE_ENTER = 'mouse-enter',
MOUSE_ENTER = 'mouse-enter-window',

/**
* @en
Expand Down
133 changes: 37 additions & 96 deletions cocos/rendering/custom/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
****************************************************************************/
import { DEBUG } from 'internal:constants';
import { Buffer, Framebuffer, LoadOp, StoreOp, Texture, Viewport } from '../../gfx';
import { assert } from '../../core';
import { VectorGraphColorMap } from './effect';
import { DefaultVisitor, depthFirstSearch, ReferenceGraphView } from './graph';
import { LayoutGraphData } from './layout-graph';
Expand All @@ -35,53 +34,51 @@ import {
RenderGraphValue,
} from './render-graph';
import { AccessType, ResourceResidency, SceneFlags } from './types';
import { hashCombineNum, hashCombineStr } from './define';
import { hashCombineKey, hashCombineStr } from './define';

function genHashValue (pass: RasterPass): void {
let hashCode = 0;
let hashCode = '';
for (const [name, raster] of pass.rasterViews) {
hashCode = hashCombineStr('raster', hashCode);
hashCode = hashCombineStr(name, hashCode);
hashCode = hashCombineStr(raster.slotName, hashCode);
hashCode = hashCombineNum(raster.accessType, hashCode);
hashCode = hashCombineNum(raster.attachmentType, hashCode);
hashCode = hashCombineNum(raster.loadOp, hashCode);
hashCode = hashCombineNum(raster.storeOp, hashCode);
hashCode = hashCombineNum(raster.clearFlags, hashCode);
hashCode = hashCombineNum(raster.clearColor.x, hashCode);
hashCode = hashCombineNum(raster.clearColor.y, hashCode);
hashCode = hashCombineNum(raster.clearColor.z, hashCode);
hashCode = hashCombineNum(raster.clearColor.w, hashCode);
hashCode = hashCombineNum(raster.slotID, hashCode);
hashCode = hashCombineNum(raster.shaderStageFlags, hashCode);
hashCode += hashCombineKey(name);
hashCode += hashCombineKey(raster.slotName);
hashCode += hashCombineKey(raster.accessType);
hashCode += hashCombineKey(raster.attachmentType);
hashCode += hashCombineKey(raster.loadOp);
hashCode += hashCombineKey(raster.storeOp);
hashCode += hashCombineKey(raster.clearFlags);
hashCode += hashCombineKey(raster.clearColor.x);
hashCode += hashCombineKey(raster.clearColor.y);
hashCode += hashCombineKey(raster.clearColor.z);
hashCode += hashCombineKey(raster.clearColor.w);
hashCode += hashCombineKey(raster.slotID);
hashCode += hashCombineKey(raster.shaderStageFlags);
}
for (const [name, computes] of pass.computeViews) {
hashCode = hashCombineStr(name, hashCode);
hashCode += hashCombineKey(name);
for (const compute of computes) {
hashCode = hashCombineStr('compute', hashCode);
hashCode = hashCombineStr(compute.name, hashCode);
hashCode = hashCombineNum(compute.accessType, hashCode);
hashCode = hashCombineNum(compute.clearFlags, hashCode);
hashCode = hashCombineNum(compute.clearValueType, hashCode);
hashCode = hashCombineNum(compute.clearValue.x, hashCode);
hashCode = hashCombineNum(compute.clearValue.y, hashCode);
hashCode = hashCombineNum(compute.clearValue.z, hashCode);
hashCode = hashCombineNum(compute.clearValue.w, hashCode);
hashCode = hashCombineNum(compute.shaderStageFlags, hashCode);
hashCode += hashCombineKey(compute.name);
hashCode += hashCombineKey(compute.accessType);
hashCode += hashCombineKey(compute.clearFlags);
hashCode += hashCombineKey(compute.clearValueType);
hashCode += hashCombineKey(compute.clearValue.x);
hashCode += hashCombineKey(compute.clearValue.y);
hashCode += hashCombineKey(compute.clearValue.z);
hashCode += hashCombineKey(compute.clearValue.w);
hashCode += hashCombineKey(compute.shaderStageFlags);
}
}
hashCode = hashCombineNum(pass.width, hashCode);
hashCode = hashCombineNum(pass.height, hashCode);
hashCode = hashCombineNum(pass.viewport.left, hashCode);
hashCode = hashCombineNum(pass.viewport.top, hashCode);
hashCode = hashCombineNum(pass.viewport.width, hashCode);
hashCode = hashCombineNum(pass.viewport.height, hashCode);
hashCode = hashCombineNum(pass.viewport.minDepth, hashCode);
hashCode = hashCombineNum(pass.viewport.maxDepth, hashCode);
hashCode = hashCombineNum(pass.showStatistics ? 1 : 0, hashCode);
pass.hashValue = hashCode;
hashCode += hashCombineKey(pass.width);
hashCode += hashCombineKey(pass.height);
hashCode += hashCombineKey(pass.viewport.left);
hashCode += hashCombineKey(pass.viewport.top);
hashCode += hashCombineKey(pass.viewport.width);
hashCode += hashCombineKey(pass.viewport.height);
hashCode += hashCombineKey(pass.viewport.minDepth);
hashCode += hashCombineKey(pass.viewport.maxDepth);
hashCode += hashCombineKey(pass.showStatistics ? 1 : 0);
pass.hashValue = hashCombineStr(hashCode);
}

const readViews: Map<string, RasterView> = new Map();
class PassVisitor implements RenderGraphVisitor {
public queueID = 0xFFFFFFFF;
public sceneID = 0xFFFFFFFF;
Expand Down Expand Up @@ -150,13 +147,6 @@ class PassVisitor implements RenderGraphVisitor {
for (const [passId, currRaster] of rasters) {
if (passId > this.passID) {
isPreRaster = true;
// TODO: Shadow map is rather special, as it will be merged into one pass later, and then this determination can be removed.
if (!this._isShadowMap(this.sceneID)) {
assert(
currRaster.loadOp === LoadOp.LOAD,
`The resource with name ${input} is being used, and the pass that uses this resource must have loadOp set to 'load'`,
);
}
}
}
for (const [passId] of computes) {
Expand All @@ -165,16 +155,12 @@ class PassVisitor implements RenderGraphVisitor {
break;
}
}
if (isPreRaster) {
assert(raster.storeOp === StoreOp.STORE, `The resource ${input} is being used, so storeOp needs to be set to 'store'`);
}
rasters.set(this.passID, raster);
} else {
const resId = resGraph.vertex(input);
const trait = resGraph.getTraits(resId);
switch (trait.residency) {
case ResourceResidency.PERSISTENT:
assert(raster.storeOp === StoreOp.STORE, `Persistent resources must have storeOp set to 'store'.`);
break;
default:
}
Expand All @@ -194,7 +180,7 @@ class PassVisitor implements RenderGraphVisitor {
}
const outputId = this.resID;
const outputName = this.context.resourceGraph.vertexName(outputId);
const readViews: Map<string, RasterView> = new Map();
readViews.clear();
const pass = this._currPass! as RasterPass;
const validPass = rg.getValid(this.passID);
for (const [readName, raster] of pass.rasterViews) {
Expand Down Expand Up @@ -462,51 +448,6 @@ export class Compiler {
context.pipeline.resourceUses.length = 0;
this._visitor.colorMap.colors.length = context.resourceGraph.nv();
depthFirstSearch(this._resourceGraph, this._visitor, this._visitor.colorMap);

if (DEBUG) {
const useContext = context.resourceContext;
for (const [name, use] of useContext) {
const resId = this._resourceGraph.vertex(name);
const trait = this._resourceGraph.getTraits(resId);
const rasterArr: number[] = Array.from(use.rasters.keys());
if (!rasterArr.length) {
continue;
}

const min = rasterArr.reduce((prev, current): number => (prev < current ? prev : current));
const firstRaster = use.rasters.get(min)!;
switch (trait.residency) {
case ResourceResidency.PERSISTENT:
assert(
firstRaster.loadOp !== LoadOp.DISCARD,
`The loadOp for persistent resources in the top-level pass cannot be set to 'discard'.`,
);
break;
case ResourceResidency.MANAGED:
assert(firstRaster.loadOp === LoadOp.CLEAR, `The loadOp for Managed resources in the top-level pass can only be set to 'clear'.`);
break;
default:
break;
}
const computeArr: number[] = Array.from(use.computes.keys());
const max = rasterArr.reduce((prev, current): number => (prev > current ? prev : current));
let maxCompute = -1;
if (computeArr.length) {
maxCompute = computeArr.reduce((prev, current): number => (prev > current ? prev : current));
}
if (max > maxCompute) {
const lastRaster = use.rasters.get(max)!;
switch (trait.residency) {
case ResourceResidency.MANAGED:
// TODO
// assert(lastRaster.storeOp === StoreOp.DISCARD, `MANAGED resources that are not being used must be set to 'discard'.`);
break;
default:
break;
}
}
}
}
}
}
const context = new CompilerContext();
Expand Down
Loading
Loading