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

Texture options immediate #6698

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions examples/src/examples/graphics/texture-array.example.mjs
Original file line number Diff line number Diff line change
@@ -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);
3 changes: 3 additions & 0 deletions src/platform/graphics/null/null-texture.js
Original file line number Diff line number Diff line change
@@ -10,6 +10,9 @@ class NullTexture {

loseContext() {
}

uploadImmediate(device, texture, immediate) {
}
}

export { NullTexture };
20 changes: 12 additions & 8 deletions src/platform/graphics/texture.js
Original file line number Diff line number Diff line change
@@ -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,31 +990,33 @@ 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;
}

/**
* 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);
}

/**
13 changes: 13 additions & 0 deletions src/platform/graphics/webgl/webgl-texture.js
Original file line number Diff line number Diff line change
@@ -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.