diff --git a/examples/src/examples/graphics/texture-array.example.mjs b/examples/src/examples/graphics/texture-array.example.mjs index 4d0e2729334..df849eb1f36 100644 --- a/examples/src/examples/graphics/texture-array.example.mjs +++ b/examples/src/examples/graphics/texture-array.example.mjs @@ -120,11 +120,11 @@ assetListLoader.load(() => { assets.aerialRocks.resource.getSource(), assets.coastSand.resource.getSource() ] - ] + ], + immediate: true }; const textureArray = new pc.Texture(app.graphicsDevice, textureArrayOptions); - textureArray.upload(); // generate mipmaps for visualization const mipmaps = generateMipmaps(textureArrayOptions.width, textureArrayOptions.height); diff --git a/src/platform/graphics/null/null-texture.js b/src/platform/graphics/null/null-texture.js index aa74db6f606..131a03b8271 100644 --- a/src/platform/graphics/null/null-texture.js +++ b/src/platform/graphics/null/null-texture.js @@ -10,6 +10,9 @@ class NullTexture { loseContext() { } + + uploadImmediate(device, texture, immediate) { + } } export { NullTexture }; diff --git a/src/platform/graphics/texture.js b/src/platform/graphics/texture.js index d56fbe5e16b..a37262e4481 100644 --- a/src/platform/graphics/texture.js +++ b/src/platform/graphics/texture.js @@ -197,6 +197,7 @@ class Texture { * of Uint8Array if options.arrayLength is defined and greater than zero. * @param {boolean} [options.storage] - Defines if texture can be used as a storage texture by * a compute shader. Defaults to false. + * @param {boolean} [options.immediate] - If set and true, the texture will be uploaded to the GPU immediately. * @example * // Create a 8x8x24-bit texture * const texture = new pc.Texture(graphicsDevice, { @@ -279,7 +280,7 @@ class Texture { this._levels = options.levels; if (this._levels) { - this.upload(); + this.upload(options.immediate ?? false); } else { this._levels = this._cubemap ? [[null, null, null, null, null, null]] : [null]; } @@ -887,8 +888,9 @@ class Texture { * @param {number} [mipLevel] - A non-negative integer specifying the image level of detail. * Defaults to 0, which represents the base image source. A level value of N, that is greater * than 0, represents the image source for the Nth mipmap reduction level. + * @param {boolean} [immediate] - When set to true it forces an immediate upload upon assignment. Defaults to false. */ - setSource(source, mipLevel = 0) { + setSource(source, mipLevel = 0, immediate = false) { let invalid = false; let width, height; @@ -968,7 +970,7 @@ class Texture { this._invalid = invalid; // reupload - this.upload(); + this.upload(immediate); } } @@ -988,15 +990,16 @@ class Texture { /** * Unlocks the currently locked mip level and uploads it to VRAM. + * @param {boolean} [immediate] - When set to true it forces an immediate upload upon unlocking. Defaults to false. */ - unlock() { + unlock(immediate = false) { if (this._lockedMode === TEXTURELOCK_NONE) { Debug.warn("pc.Texture#unlock: Attempting to unlock a texture that is not locked.", this); } // Upload the new pixel data if locked in write mode (default) if (this._lockedMode === TEXTURELOCK_WRITE) { - this.upload(); + this.upload(immediate); } this._lockedLevel = -1; this._lockedMode = TEXTURELOCK_NONE; @@ -1004,15 +1007,16 @@ class Texture { /** * Forces a reupload of the textures pixel data to graphics memory. Ordinarily, this function - * is called by internally by {@link Texture#setSource} and {@link Texture#unlock}. However, it + * is called internally by {@link Texture#setSource} and {@link Texture#unlock}. However, it * still needs to be called explicitly in the case where an HTMLVideoElement is set as the * source of the texture. Normally, this is done once every frame before video textured * geometry is rendered. + * @param {boolean} [immediate] - When set to true it forces an immediate upload. Defaults to false. */ - upload() { + upload(immediate = false) { this._needsUpload = true; this._needsMipmapsUpload = this._mipmaps; - this.impl.uploadImmediate?.(this.device, this); + this.impl.uploadImmediate(this.device, this, immediate); } /** diff --git a/src/platform/graphics/webgl/webgl-texture.js b/src/platform/graphics/webgl/webgl-texture.js index 703aac50bf2..9c4775be297 100644 --- a/src/platform/graphics/webgl/webgl-texture.js +++ b/src/platform/graphics/webgl/webgl-texture.js @@ -430,6 +430,19 @@ class WebglTexture { this._glCreated = false; } + uploadImmediate(device, texture, immediate) { + if (immediate) { + if (!texture._glTexture) { + this.initialize(device, texture); + } + + device.bindTexture(texture); + this.upload(device, texture); + texture._needsUpload = false; + texture._needsMipmapsUpload = false; + } + } + /** * @param {WebglGraphicsDevice} device - The device. * @param {Texture} texture - The texture to update.