Skip to content

Commit

Permalink
Add unit test of texelData util
Browse files Browse the repository at this point in the history
This test uploads a single texel to encodable texture formats
and then reads it back in a shader with textureLoad to check that
the values are as expected.
  • Loading branch information
austinEng committed Nov 14, 2020
1 parent 2feb998 commit d6656eb
Show file tree
Hide file tree
Showing 4 changed files with 595 additions and 64 deletions.
80 changes: 43 additions & 37 deletions src/webgpu/capability_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,56 +102,60 @@ type TextureFormatInfo = {
// Add fields as needed
};

export type TextureDataType = 'uint' | 'sint' | 'unorm' | 'snorm' | 'float' | 'ufloat';

export const kRegularTextureFormatInfo: {
readonly [k in RegularTextureFormat]: {
color: true;
bytesPerBlock: number;
blockWidth: 1;
blockHeight: 1;
dataType: TextureDataType;
componentType: GPUTextureComponentType;
} & TextureFormatInfo;
} = /* prettier-ignore */ {
// 8-bit formats
'r8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
'r8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
'r8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
'r8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
'r8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'r8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'snorm', componentType: 'float' },
'r8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'r8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
// 16-bit formats
'r16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'r16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'r16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'rg8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'rg8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'rg8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'rg8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
'r16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'r16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'r16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
'rg8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'rg8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'snorm', componentType: 'float' },
'rg8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rg8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
// 32-bit formats
'r32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'r32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'r32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rg16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rg16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rg16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgba8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgba8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgba8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgba8uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgba8sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'bgra8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'bgra8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'r32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'r32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'r32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
'rg16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rg16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'rg16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
'rgba8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'rgba8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'rgba8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'float' },
'rgba8uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rgba8sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'bgra8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'bgra8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
// Packed 32-bit formats
'rgb10a2unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rg11b10ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgb9e5ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'rgb10a2unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
'rg11b10ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'ufloat', componentType: 'float' },
'rgb9e5ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'ufloat', componentType: 'float' },
// 64-bit formats
'rg32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rg32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rg32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rgba16uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rgba16sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rgba16float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
'rg32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rg32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'rg32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
'rgba16uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rgba16sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'rgba16float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
// 128-bit formats
'rgba32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
'rgba32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
'rgba32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
'rgba32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
'rgba32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
'rgba32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
} as const;
export const kRegularTextureFormats = keysOf(kRegularTextureFormatInfo);

Expand All @@ -162,9 +166,11 @@ export const kSizedDepthStencilFormatInfo: {
readonly bytesPerBlock: number;
readonly blockWidth: 1;
readonly blockHeight: 1;
dataType: TextureDataType;
componentType: GPUTextureComponentType;
} & TextureFormatInfo;
} = /* prettier-ignore */ {
'depth32float': { renderable: true, color: false, depth: true, stencil: false, storage: false, copySrc: true, copyDst: false, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
'depth32float': { renderable: true, color: false, depth: true, stencil: false, storage: false, copySrc: true, copyDst: false, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
};
export const kSizedDepthStencilFormats = keysOf(kSizedDepthStencilFormatInfo);

Expand Down
22 changes: 21 additions & 1 deletion src/webgpu/util/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ export function floatAsNormalizedInteger(float: number, bits: number, signed: bo
}
}

export function normalizedIntegerAsFloat(integer: number, bits: number, signed: boolean): number {
if (signed) {
const max = Math.pow(2, bits - 1) - 1;
assert(integer >= -max - 1 && integer <= max);
if (integer === -max - 1) {
integer = -max;
}
return integer / max;
} else {
const max = Math.pow(2, bits) - 1;
assert(integer >= 0 && integer <= max);
return integer / max;
}
}

// Does not handle clamping, underflow, overflow, denormalized numbers
export function float32ToFloatBits(
n: number,
Expand Down Expand Up @@ -127,6 +142,11 @@ export function assertInIntegerRange(n: number, bits: number, signed: boolean):
}

export function gammaCompress(n: number): number {
n = n <= 0.0031308 ? 12.92 * n : 1.055 * Math.pow(n, 1 / 2.4) - 0.055;
n = n <= 0.0031308 ? (323 * n) / 25 : (211 * Math.pow(n, 5 / 12) - 11) / 200;
return n < 0 ? 0 : n > 1 ? 1 : n;
}

export function gammaDecompress(n: number): number {
n = n <= 0.04045 ? (n * 25) / 323 : Math.pow((200 * n + 11) / 211, 12 / 5);
return n < 0 ? 0 : n > 1 ? 1 : n;
}
Loading

0 comments on commit d6656eb

Please sign in to comment.