Skip to content

Commit

Permalink
Merge branch 'v3.8.5' of https://github.com/cocos/cocos-engine into 3…
Browse files Browse the repository at this point in the history
…85-reduce-gfx-code

# Conflicts:
#	cocos/gfx/webgl/webgl-commands.ts
#	cocos/gfx/webgl2/webgl2-commands.ts
  • Loading branch information
dumganhar committed Sep 27, 2024
2 parents 2f9abc3 + 39fb0a5 commit d726e8c
Show file tree
Hide file tree
Showing 36 changed files with 747 additions and 827 deletions.
5 changes: 2 additions & 3 deletions cocos/core/utils/js-typed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@ export function getClassName (objOrCtor: any): string {
// for browsers which have name property in the constructor of the object, such as chrome
if (objOrCtor.name) {
ret = objOrCtor.name;
}
if (objOrCtor.toString) {
} else if (objOrCtor.toString) {
let arr;
const str = objOrCtor.toString();
if (str.charAt(0) === '[') {
Expand All @@ -261,7 +260,7 @@ export function getClassName (objOrCtor: any): string {
} else {
// str is function objectClass () {} for IE Firefox
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
arr = /function\s*(\w+)/.exec(str);
arr = /^function\s*(\w+)/.exec(str);
}
if (arr && arr.length === 2) {
ret = arr[1];
Expand Down
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 { WebGLEXT } from './webgl-define';
import { WebGLDevice } from './webgl-device';
import {
Expand All @@ -40,6 +41,7 @@ import {
import { WebGLConstants } from '../gl-constants';
import { assertID, debugID, error, errorID } from '../../core/platform/debug';
import { cclegacy } from '../../core/global-exports';
import { OS } from '../../../pal/system-info/enum-type';

const max = Math.max;
const min = Math.min;
Expand Down Expand Up @@ -668,7 +670,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 @@ -48,6 +49,7 @@ import {
import { error, errorID, assertID, debugID } from '../../core/platform/debug';
import { WebGLConstants } from '../gl-constants';
import { cclegacy } from '../../core/global-exports';
import { OS } from '../../../pal/system-info/enum-type';

const WebGLWraps: GLenum[] = [
WebGLConstants.REPEAT,
Expand Down Expand Up @@ -841,7 +843,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 @@ -862,7 +870,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 @@ -875,7 +889,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

0 comments on commit d726e8c

Please sign in to comment.