|
|
@@ -32,25 +32,82 @@ const _compareToWebGPU = {
|
|
|
|
|
|
const _flipMap = [ 0, 1, 3, 2, 4, 5 ];
|
|
|
|
|
|
+/**
|
|
|
+ * A WebGPU backend utility module for managing textures.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ */
|
|
|
class WebGPUTextureUtils {
|
|
|
|
|
|
+ /**
|
|
|
+ * Constructs a new utility object.
|
|
|
+ *
|
|
|
+ * @param {WebGPUBackend} backend - The WebGPU backend.
|
|
|
+ */
|
|
|
constructor( backend ) {
|
|
|
|
|
|
+ /**
|
|
|
+ * A reference to the WebGPU backend.
|
|
|
+ *
|
|
|
+ * @type {WebGPUBackend}
|
|
|
+ */
|
|
|
this.backend = backend;
|
|
|
|
|
|
+ /**
|
|
|
+ * A reference to the pass utils.
|
|
|
+ *
|
|
|
+ * @type {WebGPUTexturePassUtils?}
|
|
|
+ * @default null
|
|
|
+ */
|
|
|
this._passUtils = null;
|
|
|
|
|
|
+ /**
|
|
|
+ * A dictionary for managing default textures. The key
|
|
|
+ * is the texture format, the value the texture object.
|
|
|
+ *
|
|
|
+ * @type {Object<String,Texture>}
|
|
|
+ */
|
|
|
this.defaultTexture = {};
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A dictionary for managing default cube textures. The key
|
|
|
+ * is the texture format, the value the texture object.
|
|
|
+ *
|
|
|
+ * @type {Object<String,CubeTexture>}
|
|
|
+ */
|
|
|
this.defaultCubeTexture = {};
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A default video frame.
|
|
|
+ *
|
|
|
+ * @type {VideoFrame?}
|
|
|
+ * @default null
|
|
|
+ */
|
|
|
this.defaultVideoFrame = null;
|
|
|
|
|
|
+ /**
|
|
|
+ * Represents the color attachment of the default framebuffer.
|
|
|
+ *
|
|
|
+ * @type {GPUTexture?}
|
|
|
+ * @default null
|
|
|
+ */
|
|
|
this.colorBuffer = null;
|
|
|
|
|
|
+ /**
|
|
|
+ * Represents the depth attachment of the default framebuffer.
|
|
|
+ *
|
|
|
+ * @type {DepthTexture}
|
|
|
+ */
|
|
|
this.depthTexture = new DepthTexture();
|
|
|
this.depthTexture.name = 'depthBuffer';
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a GPU sampler for the given texture.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture to create the sampler for.
|
|
|
+ */
|
|
|
createSampler( texture ) {
|
|
|
|
|
|
const backend = this.backend;
|
|
|
@@ -86,6 +143,12 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a default texture for the given texture that can be used
|
|
|
+ * as a placeholder until the actual texture is ready for usage.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture to create a default texture for.
|
|
|
+ */
|
|
|
createDefaultTexture( texture ) {
|
|
|
|
|
|
let textureGPU;
|
|
|
@@ -110,6 +173,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Defines a texture on the GPU for the given texture object.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ * @param {Object} [options={}] - Optional configuration parameter.
|
|
|
+ * @return {undefined}
|
|
|
+ */
|
|
|
createTexture( texture, options = {} ) {
|
|
|
|
|
|
const backend = this.backend;
|
|
|
@@ -221,6 +291,11 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Destroys the GPU data for the given texture object.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ */
|
|
|
destroyTexture( texture ) {
|
|
|
|
|
|
const backend = this.backend;
|
|
|
@@ -234,6 +309,11 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Destroys the GPU sampler for the given texture.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture to destroy the sampler for.
|
|
|
+ */
|
|
|
destroySampler( texture ) {
|
|
|
|
|
|
const backend = this.backend;
|
|
|
@@ -243,6 +323,11 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Generates mipmaps for the given texture.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ */
|
|
|
generateMipmaps( texture ) {
|
|
|
|
|
|
const textureData = this.backend.get( texture );
|
|
|
@@ -269,6 +354,12 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the color buffer representing the color
|
|
|
+ * attachment of the default framebuffer.
|
|
|
+ *
|
|
|
+ * @return {GPUTexture} The color buffer.
|
|
|
+ */
|
|
|
getColorBuffer() {
|
|
|
|
|
|
if ( this.colorBuffer ) this.colorBuffer.destroy();
|
|
|
@@ -292,6 +383,14 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the depth buffer representing the depth
|
|
|
+ * attachment of the default framebuffer.
|
|
|
+ *
|
|
|
+ * @param {Boolean} [depth=true] - Whether depth is enabled or not.
|
|
|
+ * @param {Boolean} [stencil=false] - Whether stencil is enabled or not.
|
|
|
+ * @return {GPUTexture} The depth buffer.
|
|
|
+ */
|
|
|
getDepthBuffer( depth = true, stencil = false ) {
|
|
|
|
|
|
const backend = this.backend;
|
|
|
@@ -338,6 +437,12 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Uploads the updated texture data to the GPU.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ * @param {Object} [options={}] - Optional configuration parameter.
|
|
|
+ */
|
|
|
updateTexture( texture, options ) {
|
|
|
|
|
|
const textureData = this.backend.get( texture );
|
|
|
@@ -389,6 +494,18 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns texture data as a typed array.
|
|
|
+ *
|
|
|
+ * @async
|
|
|
+ * @param {Texture} texture - The texture to copy.
|
|
|
+ * @param {Number} x - The x coordinate of the copy origin.
|
|
|
+ * @param {Number} y - The y coordinate of the copy origin.
|
|
|
+ * @param {Number} width - The width of the copy.
|
|
|
+ * @param {Number} height - The height of the copy.
|
|
|
+ * @param {Number} faceIndex - The face index.
|
|
|
+ * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operations has finished.
|
|
|
+ */
|
|
|
async copyTextureToBuffer( texture, x, y, width, height, faceIndex ) {
|
|
|
|
|
|
const device = this.backend.device;
|
|
|
@@ -438,6 +555,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns `true` if the given texture is an environment map.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ * @return {Boolean} Whether the given texture is an environment map or not.
|
|
|
+ */
|
|
|
_isEnvironmentTexture( texture ) {
|
|
|
|
|
|
const mapping = texture.mapping;
|
|
|
@@ -446,6 +570,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the default GPU texture for the given format.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {String} format - The GPU format.
|
|
|
+ * @return {GPUTexture} The GPU texture.
|
|
|
+ */
|
|
|
_getDefaultTextureGPU( format ) {
|
|
|
|
|
|
let defaultTexture = this.defaultTexture[ format ];
|
|
|
@@ -466,6 +597,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the default GPU cube texture for the given format.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {String} format - The GPU format.
|
|
|
+ * @return {GPUTexture} The GPU texture.
|
|
|
+ */
|
|
|
_getDefaultCubeTextureGPU( format ) {
|
|
|
|
|
|
let defaultCubeTexture = this.defaultTexture[ format ];
|
|
|
@@ -486,6 +624,12 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the default video frame used as default data in context of video textures.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @return {VideoFrame} The video frame.
|
|
|
+ */
|
|
|
_getDefaultVideoFrame() {
|
|
|
|
|
|
let defaultVideoFrame = this.defaultVideoFrame;
|
|
|
@@ -507,6 +651,15 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Uploads cube texture image data to the GPU memory.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Array} images - The cube image data.
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture.
|
|
|
+ * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
|
|
|
+ * @param {Boolean} flipY - Whether to flip texture data along their vertical axis or not.
|
|
|
+ */
|
|
|
_copyCubeMapToTexture( images, textureGPU, textureDescriptorGPU, flipY ) {
|
|
|
|
|
|
for ( let i = 0; i < 6; i ++ ) {
|
|
|
@@ -529,6 +682,16 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Uploads texture image data to the GPU memory.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {HTMLImageElement|ImageBitmap|HTMLCanvasElement} image - The image data.
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture.
|
|
|
+ * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
|
|
|
+ * @param {Number} originDepth - The origin depth.
|
|
|
+ * @param {Boolean} flipY - Whether to flip texture data along their vertical axis or not.
|
|
|
+ */
|
|
|
_copyImageToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY ) {
|
|
|
|
|
|
const device = this.backend.device;
|
|
|
@@ -555,6 +718,12 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the pass utils singleton.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @return {WebGPUTexturePassUtils} The utils instance.
|
|
|
+ */
|
|
|
_getPassUtils() {
|
|
|
|
|
|
let passUtils = this._passUtils;
|
|
|
@@ -569,18 +738,45 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Generates mipmaps for the given GPU texture.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture object.
|
|
|
+ * @param {Object} textureDescriptorGPU - The texture descriptor.
|
|
|
+ * @param {Number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view.
|
|
|
+ */
|
|
|
_generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer = 0 ) {
|
|
|
|
|
|
this._getPassUtils().generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer );
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Flip the contents of the given GPU texture along its vertical axis.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture object.
|
|
|
+ * @param {Object} textureDescriptorGPU - The texture descriptor.
|
|
|
+ * @param {Number} [originDepth=0] - The origin depth.
|
|
|
+ */
|
|
|
_flipY( textureGPU, textureDescriptorGPU, originDepth = 0 ) {
|
|
|
|
|
|
this._getPassUtils().flipY( textureGPU, textureDescriptorGPU, originDepth );
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Uploads texture buffer data to the GPU memory.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Object} image - An object defining the image buffer data.
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture.
|
|
|
+ * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
|
|
|
+ * @param {Number} originDepth - The origin depth.
|
|
|
+ * @param {Boolean} flipY - Whether to flip texture data along their vertical axis or not.
|
|
|
+ * @param {Number} [depth=0] - TODO.
|
|
|
+ */
|
|
|
_copyBufferToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY, depth = 0 ) {
|
|
|
|
|
|
// @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture()
|
|
|
@@ -618,6 +814,14 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Uploads compressed texture data to the GPU memory.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Array<Object>} mipmaps - An array with mipmap data.
|
|
|
+ * @param {GPUTexture} textureGPU - The GPU texture.
|
|
|
+ * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
|
|
|
+ */
|
|
|
_copyCompressedBufferToTexture( mipmaps, textureGPU, textureDescriptorGPU ) {
|
|
|
|
|
|
// @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture()
|
|
|
@@ -665,10 +869,16 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * This method is only relevant for compressed texture formats. It returns a block
|
|
|
+ * data descriptor for the given GPU compressed texture format.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {String} format - The GPU compressed texture format.
|
|
|
+ * @return {Object} The block data descriptor.
|
|
|
+ */
|
|
|
_getBlockData( format ) {
|
|
|
|
|
|
- // this method is only relevant for compressed texture formats
|
|
|
-
|
|
|
if ( format === GPUTextureFormat.BC1RGBAUnorm || format === GPUTextureFormat.BC1RGBAUnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; // DXT1
|
|
|
if ( format === GPUTextureFormat.BC2RGBAUnorm || format === GPUTextureFormat.BC2RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT3
|
|
|
if ( format === GPUTextureFormat.BC3RGBAUnorm || format === GPUTextureFormat.BC3RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT5
|
|
|
@@ -702,6 +912,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Converts the three.js uv wrapping constants to GPU address mode constants.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Number} value - The three.js constant defining a uv wrapping mode.
|
|
|
+ * @return {String} The GPU address mode.
|
|
|
+ */
|
|
|
_convertAddressMode( value ) {
|
|
|
|
|
|
let addressMode = GPUAddressMode.ClampToEdge;
|
|
|
@@ -720,6 +937,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Converts the three.js filter constants to GPU filter constants.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Number} value - The three.js constant defining a filter mode.
|
|
|
+ * @return {String} The GPU filter mode.
|
|
|
+ */
|
|
|
_convertFilterMode( value ) {
|
|
|
|
|
|
let filterMode = GPUFilterMode.Linear;
|
|
|
@@ -734,6 +958,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the bytes-per-texel value for the given GPU texture format.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {String} format - The GPU texture format.
|
|
|
+ * @return {Number} The bytes-per-texel.
|
|
|
+ */
|
|
|
_getBytesPerTexel( format ) {
|
|
|
|
|
|
// 8-bit formats
|
|
|
@@ -790,6 +1021,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the corresponding typed array type for the given GPU texture format.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {String} format - The GPU texture format.
|
|
|
+ * @return {TypedArray.constructor} The typed array type.
|
|
|
+ */
|
|
|
_getTypedArrayType( format ) {
|
|
|
|
|
|
if ( format === GPUTextureFormat.R8Uint ) return Uint8Array;
|
|
|
@@ -840,6 +1078,13 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the GPU dimensions for the given texture.
|
|
|
+ *
|
|
|
+ * @private
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ * @return {String} The GPU dimension.
|
|
|
+ */
|
|
|
_getDimension( texture ) {
|
|
|
|
|
|
let dimension;
|
|
|
@@ -860,6 +1105,14 @@ class WebGPUTextureUtils {
|
|
|
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Returns the GPU format for the given texture.
|
|
|
+ *
|
|
|
+ * @param {Texture} texture - The texture.
|
|
|
+ * @param {GPUDevice?} [device=null] - The GPU device which is used for feature detection.
|
|
|
+ * It is not necessary to apply the device for most formats.
|
|
|
+ * @return {String} The GPU format.
|
|
|
+ */
|
|
|
export function getFormat( texture, device = null ) {
|
|
|
|
|
|
const format = texture.format;
|