Skip to content

Commit

Permalink
Merge pull request #13284 from Popov72/ktx-new-decoders
Browse files Browse the repository at this point in the history
KTXDecoder: Update and add new universal transcoders
  • Loading branch information
sebavan authored Nov 28, 2022
2 parents ca58e21 + 4540755 commit 7e3ed2b
Show file tree
Hide file tree
Showing 21 changed files with 250 additions and 64 deletions.
44 changes: 37 additions & 7 deletions packages/dev/core/src/Misc/khronosTextureContainer2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ function applyConfig(urls: typeof KhronosTextureContainer2.URLConfig): void {
KTX2DECODER.LiteTranscoder_UASTC_RGBA_SRGB.WasmModuleURL = urls.wasmUASTCToRGBA_SRGB;
}

if (urls.wasmUASTCToR8_UNORM !== null) {
KTX2DECODER.LiteTranscoder_UASTC_R8_UNORM.WasmModuleURL = urls.wasmUASTCToR8_UNORM;
}

if (urls.wasmUASTCToRG8_UNORM !== null) {
KTX2DECODER.LiteTranscoder_UASTC_RG8_UNORM.WasmModuleURL = urls.wasmUASTCToRG8_UNORM;
}

if (urls.jsMSCTranscoder !== null) {
KTX2DECODER.MSCTranscoder.JSModuleURL = urls.jsMSCTranscoder;
}
Expand Down Expand Up @@ -59,6 +67,8 @@ export class KhronosTextureContainer2 {
* URLConfig.wasmUASTCToBC7
* URLConfig.wasmUASTCToRGBA_UNORM
* URLConfig.wasmUASTCToRGBA_SRGB
* URLConfig.wasmUASTCToR8_UNORM
* URLConfig.wasmUASTCToRG8_UNORM
* URLConfig.jsMSCTranscoder
* URLConfig.wasmMSCTranscoder
* URLConfig.wasmZSTDDecoder
Expand All @@ -70,6 +80,8 @@ export class KhronosTextureContainer2 {
wasmUASTCToBC7: Nullable<string>;
wasmUASTCToRGBA_UNORM: Nullable<string>;
wasmUASTCToRGBA_SRGB: Nullable<string>;
wasmUASTCToR8_UNORM: Nullable<string>;
wasmUASTCToRG8_UNORM: Nullable<string>;
jsMSCTranscoder: Nullable<string>;
wasmMSCTranscoder: Nullable<string>;
wasmZSTDDecoder: Nullable<string>;
Expand All @@ -79,6 +91,8 @@ export class KhronosTextureContainer2 {
wasmUASTCToBC7: null,
wasmUASTCToRGBA_UNORM: null,
wasmUASTCToRGBA_SRGB: null,
wasmUASTCToR8_UNORM: null,
wasmUASTCToRG8_UNORM: null,
jsMSCTranscoder: null,
wasmMSCTranscoder: null,
wasmZSTDDecoder: null,
Expand Down Expand Up @@ -111,6 +125,8 @@ export class KhronosTextureContainer2 {
wasmUASTCToBC7: getAbsoluteUrlOrNull(this.URLConfig.wasmUASTCToBC7),
wasmUASTCToRGBA_UNORM: getAbsoluteUrlOrNull(this.URLConfig.wasmUASTCToRGBA_UNORM),
wasmUASTCToRGBA_SRGB: getAbsoluteUrlOrNull(this.URLConfig.wasmUASTCToRGBA_SRGB),
wasmUASTCToR8_UNORM: getAbsoluteUrlOrNull(this.URLConfig.wasmUASTCToR8_UNORM),
wasmUASTCToRG8_UNORM: getAbsoluteUrlOrNull(this.URLConfig.wasmUASTCToRG8_UNORM),
jsMSCTranscoder: getAbsoluteUrlOrNull(this.URLConfig.jsMSCTranscoder),
wasmMSCTranscoder: getAbsoluteUrlOrNull(this.URLConfig.wasmMSCTranscoder),
wasmZSTDDecoder: getAbsoluteUrlOrNull(this.URLConfig.wasmZSTDDecoder),
Expand Down Expand Up @@ -263,11 +279,25 @@ export class KhronosTextureContainer2 {
options.transcoderName = data.transcoderName;
}

if (data.transcodedFormat === 0x8058 /* RGBA8 */) {
internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
internalTexture.format = Constants.TEXTUREFORMAT_RGBA;
} else {
internalTexture.format = data.transcodedFormat;
let isUncompressedFormat = true;

switch (data.transcodedFormat) {
case 0x8058 /* RGBA8 */:
internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
internalTexture.format = Constants.TEXTUREFORMAT_RGBA;
break;
case 0x8229 /* R8 */:
internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
internalTexture.format = Constants.TEXTUREFORMAT_R;
break;
case 0x822b /* RG8 */:
internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
internalTexture.format = Constants.TEXTUREFORMAT_RG;
break;
default:
internalTexture.format = data.transcodedFormat;
isUncompressedFormat = false;
break;
}

internalTexture._gammaSpace = data.isInGammaSpace;
Expand All @@ -284,8 +314,8 @@ export class KhronosTextureContainer2 {
throw new Error("KTX2 container - could not transcode one of the image");
}

if (data.transcodedFormat === 0x8058 /* RGBA8 */) {
// uncompressed RGBA
if (isUncompressedFormat) {
// uncompressed RGBA / R8 / RG8
internalTexture.width = mipmap.width; // need to set width/height so that the call to _uploadDataToTextureDirectly uses the right dimensions
internalTexture.height = mipmap.height;

Expand Down

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 3 additions & 2 deletions packages/tools/babylonServer/src/ktx2Decoder/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as KTX2Decoder from "@tools/ktx2decoder";
/* eslint-disable import/no-internal-modules */
import * as KTX2Decoder from "../../../ktx2Decoder/src/index";

const globalObject = typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : undefined;
if (typeof globalObject !== "undefined") {
(<any>globalObject).KTX2DECODER = KTX2Decoder;
}

export * from "@tools/ktx2decoder";
export * from "../../../ktx2Decoder/src/index";
12 changes: 8 additions & 4 deletions packages/tools/ktx2Decoder/src/Transcoders/liteTranscoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ export class LiteTranscoder extends Transcoder {
height: number,
uncompressedByteLength: number,
encodedData: Uint8Array,
forceRGBA = false
uncompressedNumComponents?: number
): [Uint8Array, Uint8Array | null, number] {
const nBlocks = ((width + 3) >> 2) * ((height + 3) >> 2);

if (forceRGBA) {
uncompressedByteLength = width * ((height + 3) >> 2) * 4 * 4;
if (uncompressedNumComponents !== undefined) {
uncompressedByteLength = width * ((height + 3) >> 2) * 4 * uncompressedNumComponents;
}

const texMemoryPages = ((nBlocks * 16 + 65535 + (this._transcodeInPlace ? 0 : uncompressedByteLength)) >> 16) + 1;
Expand All @@ -88,7 +88,11 @@ export class LiteTranscoder extends Transcoder {

const uncompressedTextureView = this._transcodeInPlace
? null
: new Uint8Array(this._memoryManager.wasmMemory.buffer, 65536 + nBlocks * 16, forceRGBA ? width * height * 4 : uncompressedByteLength);
: new Uint8Array(
this._memoryManager.wasmMemory.buffer,
65536 + nBlocks * 16,
uncompressedNumComponents !== undefined ? width * height * uncompressedNumComponents : uncompressedByteLength
);

textureView.set(encodedData);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class LiteTranscoder_UASTC_ASTC extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/uastc_astc.wasm";
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/uastc_astc.wasm";

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class LiteTranscoder_UASTC_BC7 extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/uastc_bc7.wasm";
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/uastc_bc7.wasm";

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { sourceTextureFormat, transcodeTarget } from "../transcoder";
import { LiteTranscoder } from "./liteTranscoder";
import type { KTX2FileReader, IKTX2_ImageDesc } from "../ktx2FileReader";

/**
* @internal
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export class LiteTranscoder_UASTC_R8_UNORM extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder (srgb)
*/
public static WasmModuleURL = "https://preview.babylonjs.com/1/uastc_r8_unorm.wasm";

public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
return src === sourceTextureFormat.UASTC4x4 && dst === transcodeTarget.R8;
}

public static Name = "UniversalTranscoder_UASTC_R8_UNORM";

public getName(): string {
return LiteTranscoder_UASTC_R8_UNORM.Name;
}

public initialize(): void {
super.initialize();
this._transcodeInPlace = false;
this.setModulePath(LiteTranscoder_UASTC_R8_UNORM.WasmModuleURL);
}

public transcode(
src: sourceTextureFormat,
dst: transcodeTarget,
level: number,
width: number,
height: number,
uncompressedByteLength: number,
ktx2Reader: KTX2FileReader,
imageDesc: IKTX2_ImageDesc | null,
encodedData: Uint8Array
): Promise<Uint8Array | null> {
return this._loadModule().then((moduleWrapper: any) => {
const transcoder: any = moduleWrapper.module;
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, 1);

return transcoder.decode(width, height) === 0 ? uncompressedTextureView!.slice() : null;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { sourceTextureFormat, transcodeTarget } from "../transcoder";
import { LiteTranscoder } from "./liteTranscoder";
import type { KTX2FileReader, IKTX2_ImageDesc } from "../ktx2FileReader";

/**
* @internal
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export class LiteTranscoder_UASTC_RG8_UNORM extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder (srgb)
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/uastc_rg8_unorm.wasm";

public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
return src === sourceTextureFormat.UASTC4x4 && dst === transcodeTarget.RG8;
}

public static Name = "UniversalTranscoder_UASTC_RG8_UNORM";

public getName(): string {
return LiteTranscoder_UASTC_RG8_UNORM.Name;
}

public initialize(): void {
super.initialize();
this._transcodeInPlace = false;
this.setModulePath(LiteTranscoder_UASTC_RG8_UNORM.WasmModuleURL);
}

public transcode(
src: sourceTextureFormat,
dst: transcodeTarget,
level: number,
width: number,
height: number,
uncompressedByteLength: number,
ktx2Reader: KTX2FileReader,
imageDesc: IKTX2_ImageDesc | null,
encodedData: Uint8Array
): Promise<Uint8Array | null> {
return this._loadModule().then((moduleWrapper: any) => {
const transcoder: any = moduleWrapper.module;
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, 2);

return transcoder.decode(width, height) === 0 ? uncompressedTextureView!.slice() : null;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class LiteTranscoder_UASTC_RGBA_SRGB extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder (srgb)
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/uastc_rgba32_srgb.wasm";
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/uastc_rgba8_srgb_v2.wasm";

public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
return src === sourceTextureFormat.UASTC4x4 && dst === transcodeTarget.RGBA32 && isInGammaSpace;
Expand Down Expand Up @@ -41,9 +41,9 @@ export class LiteTranscoder_UASTC_RGBA_SRGB extends LiteTranscoder {
): Promise<Uint8Array | null> {
return this._loadModule().then((moduleWrapper: any) => {
const transcoder: any = moduleWrapper.module;
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, true);
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, 4);

return transcoder.decodeRGBA32(width, height) === 0 ? uncompressedTextureView!.slice() : null;
return transcoder.decode(width, height) === 0 ? uncompressedTextureView!.slice() : null;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class LiteTranscoder_UASTC_RGBA_UNORM extends LiteTranscoder {
/**
* URL to use when loading the wasm module for the transcoder (unorm)
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/uastc_rgba32_unorm.wasm";
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/uastc_rgba8_unorm_v2.wasm";

public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget, isInGammaSpace: boolean): boolean {
return src === sourceTextureFormat.UASTC4x4 && dst === transcodeTarget.RGBA32 && !isInGammaSpace;
Expand Down Expand Up @@ -41,9 +41,9 @@ export class LiteTranscoder_UASTC_RGBA_UNORM extends LiteTranscoder {
): Promise<Uint8Array | null> {
return this._loadModule().then((moduleWrapper: any) => {
const transcoder: any = moduleWrapper.module;
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, true);
const [, uncompressedTextureView] = this._prepareTranscoding(width, height, uncompressedByteLength, encodedData, 4);

return transcoder.decodeRGBA32(width, height) === 0 ? uncompressedTextureView!.slice() : null;
return transcoder.decode(width, height) === 0 ? uncompressedTextureView!.slice() : null;
});
}
}
4 changes: 2 additions & 2 deletions packages/tools/ktx2Decoder/src/Transcoders/mscTranscoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export class MSCTranscoder extends Transcoder {
/**
* URL to use when loading the MSC transcoder
*/
public static JSModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/msc_basis_transcoder.js";
public static JSModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/msc_basis_transcoder.js";
/**
* URL to use when loading the wasm module for the transcoder
*/
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/msc_basis_transcoder.wasm";
public static WasmModuleURL = "https://preview.babylonjs.com/ktx2Transcoders/1/msc_basis_transcoder.wasm";

public static UseFromWorkerThread = true;

Expand Down
14 changes: 13 additions & 1 deletion packages/tools/ktx2Decoder/src/ktx2Decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { LiteTranscoder_UASTC_ASTC } from "./Transcoders/liteTranscoder_UASTC_AS
import { LiteTranscoder_UASTC_BC7 } from "./Transcoders/liteTranscoder_UASTC_BC7";
import { LiteTranscoder_UASTC_RGBA_UNORM } from "./Transcoders/liteTranscoder_UASTC_RGBA_UNORM";
import { LiteTranscoder_UASTC_RGBA_SRGB } from "./Transcoders/liteTranscoder_UASTC_RGBA_SRGB";
import { LiteTranscoder_UASTC_R8_UNORM } from "./Transcoders/liteTranscoder_UASTC_R8_UNORM";
import { LiteTranscoder_UASTC_RG8_UNORM } from "./Transcoders/liteTranscoder_UASTC_RG8_UNORM";
import { MSCTranscoder } from "./Transcoders/mscTranscoder";
import { transcodeTarget, sourceTextureFormat } from "./transcoder";
import { ZSTDDecoder } from "./zstddec";
Expand Down Expand Up @@ -50,15 +52,23 @@ export interface IKTX2DecoderOptions {
/** use RGBA format if ASTC and BC7 are not available as transcoded format */
useRGBAIfASTCBC7NotAvailableWhenUASTC?: boolean;

/** force to always use RGBA for transcoded format */
/** force to always use (uncompressed) RGBA for transcoded format */
forceRGBA?: boolean;

/** force to always use (uncompressed) R8 for transcoded format */
forceR8?: boolean;

/** force to always use (uncompressed) RG8 for transcoded format */
forceRG8?: boolean;

/**
* list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are:
* UniversalTranscoder_UASTC_ASTC
* UniversalTranscoder_UASTC_BC7
* UniversalTranscoder_UASTC_RGBA_UNORM
* UniversalTranscoder_UASTC_RGBA_SRGB
* UniversalTranscoder_UASTC_R8_UNORM
* UniversalTranscoder_UASTC_RG8_UNORM
* MSCTranscoder
*/
bypassTranscoders?: string[];
Expand Down Expand Up @@ -212,4 +222,6 @@ TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_ASTC);
TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_BC7);
TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_RGBA_UNORM);
TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_RGBA_SRGB);
TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_R8_UNORM);
TranscoderManager.RegisterTranscoder(LiteTranscoder_UASTC_RG8_UNORM);
TranscoderManager.RegisterTranscoder(MSCTranscoder); // catch all transcoder - will throw an error if the format can't be transcoded
Loading

0 comments on commit 7e3ed2b

Please sign in to comment.