diff --git a/cocos/gfx/base/define.ts b/cocos/gfx/base/define.ts index 235e0880c8e..627c192b7b9 100644 --- a/cocos/gfx/base/define.ts +++ b/cocos/gfx/base/define.ts @@ -409,6 +409,7 @@ export enum TextureFlagBit { EXTERNAL_NORMAL = 0x8, // External normal texture LAZILY_ALLOCATED = 0x10, // Try lazily allocated mode. MUTABLE_VIEW_FORMAT = 0x40, // texture view as different format + MUTABLE_STORAGE = 0x80, // mutable storage for gl } export enum FormatFeatureBit { diff --git a/cocos/gfx/webgl2/webgl2-commands.ts b/cocos/gfx/webgl2/webgl2-commands.ts index 80f4caab35c..7938358dc41 100644 --- a/cocos/gfx/webgl2/webgl2-commands.ts +++ b/cocos/gfx/webgl2/webgl2-commands.ts @@ -681,6 +681,7 @@ export class WebGL2CmdDraw extends WebGL2CmdObject { } public clear (): void { + // noop } } @@ -1087,6 +1088,8 @@ export function WebGL2CmdFuncCreateTexture (device: WebGL2Device, gpuTexture: IW w = Math.max(1, w >> 1); h = Math.max(1, h >> 1); } + } else if (gpuTexture.flags & TextureFlagBit.MUTABLE_STORAGE) { + gl.texImage2D(gl.TEXTURE_2D, 0, gpuTexture.glInternalFmt, w, h, 0, gpuTexture.glFormat, gpuTexture.glType, null); } else { gl.texStorage2D(gl.TEXTURE_2D, gpuTexture.mipLevel, gpuTexture.glInternalFmt, w, h); } @@ -2849,7 +2852,7 @@ export function WebGL2CmdFuncCopyTexImagesToTexture ( switch (gpuTexture.glTarget) { case gl.TEXTURE_2D: { - if (toUseTexImage2D(texImages, regions)) { + if ((gpuTexture.flags & TextureFlagBit.MUTABLE_STORAGE) || toUseTexImage2D(texImages, regions)) { gl.texImage2D( gl.TEXTURE_2D, regions[0].texSubres.mipLevel, diff --git a/native/cocos/renderer/gfx-base/GFXDef-common.h b/native/cocos/renderer/gfx-base/GFXDef-common.h index 32712dbba97..84926c05202 100644 --- a/native/cocos/renderer/gfx-base/GFXDef-common.h +++ b/native/cocos/renderer/gfx-base/GFXDef-common.h @@ -479,6 +479,7 @@ enum class TextureFlagBit : uint32_t { EXTERNAL_NORMAL = 0x8, // External normal texture LAZILY_ALLOCATED = 0x10, // Try lazily allocated mode. MUTABLE_VIEW_FORMAT = 0x40, // texture view as different format + MUTABLE_STORAGE = 0x80, // mutable storage for gl image }; using TextureFlags = TextureFlagBit; CC_ENUM_BITWISE_OPERATORS(TextureFlagBit); diff --git a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp index 2498af22fe1..6236321fddc 100644 --- a/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp +++ b/native/cocos/renderer/gfx-gles3/GLES3Commands.cpp @@ -843,7 +843,12 @@ static void textureStorage(GLES3Device *device, GLES3GPUTexture *gpuTexture) { } else { auto target = hasFlag(gpuTexture->flags, TextureFlagBit::EXTERNAL_OES) ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; GL_CHECK(glBindTexture(target, gpuTexture->glTexture)); - GL_CHECK(glTexStorage2D(target, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h)); + if (hasFlag(gpuTexture->flags, TextureFlagBit::MUTABLE_STORAGE)) { + GL_CHECK(glTexImage2D(GL_TEXTURE_2D, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h, 0, + gpuTexture->glFormat, gpuTexture->glType, nullptr)); + } else { + GL_CHECK(glTexStorage2D(GL_TEXTURE_2D, gpuTexture->mipLevel, gpuTexture->glInternalFmt, w, h)); + } } break; case TextureType::TEX3D: @@ -2736,6 +2741,16 @@ void cmdFuncGLES3CopyBuffersToTexture(GLES3Device *device, const uint8_t *const gpuTexture->glFormat, memSize, (GLvoid *)buff)); + } else if (hasFlag(gpuTexture->flags, TextureFlagBit::MUTABLE_STORAGE)) { + GL_CHECK(glTexImage2D(GL_TEXTURE_2D, + gpuTexture->mipLevel, + gpuTexture->glInternalFmt, + destWidth, + destHeight, + 0, + gpuTexture->glFormat, + gpuTexture->glType, + (GLvoid *)buff)); } else { GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, mipLevel,