summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js')
-rw-r--r--testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js158
1 files changed, 60 insertions, 98 deletions
diff --git a/testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js b/testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js
index a4b8247f56..57768e7abc 100644
--- a/testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js
+++ b/testing/web-platform/mozilla/tests/webgpu/webgpu/shader/execution/expression/unary/i32_conversion.spec.js
@@ -4,104 +4,14 @@
Execution Tests for the i32 conversion operations
`;import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { GPUTest } from '../../../../gpu_test.js';
-import { kValue } from '../../../../util/constants.js';
-import {
- bool,
- f32,
- f16,
- i32,
- TypeBool,
- TypeF32,
- TypeF16,
- TypeI32,
- TypeU32,
- u32 } from
-'../../../../util/conversion.js';
-import {
- fullF32Range,
- fullF16Range,
- fullI32Range,
- fullU32Range,
- quantizeToF32,
- quantizeToF16 } from
-'../../../../util/math.js';
-import { reinterpretU32AsI32 } from '../../../../util/reinterpret.js';
-import { makeCaseCache } from '../case_cache.js';
-import { allInputSources, run } from '../expression.js';
+import { Type } from '../../../../util/conversion.js';
+import { allInputSources, run, onlyConstInputSource } from '../expression.js';
+import { d } from './i32_conversion.cache.js';
import { unary } from './unary.js';
export const g = makeTestGroup(GPUTest);
-export const d = makeCaseCache('unary/i32_conversion', {
- bool: () => {
- return [
- { input: bool(true), expected: i32(1) },
- { input: bool(false), expected: i32(0) }];
-
- },
- u32: () => {
- return fullU32Range().map((u) => {
- return { input: u32(u), expected: i32(reinterpretU32AsI32(u)) };
- });
- },
- i32: () => {
- return fullI32Range().map((i) => {
- return { input: i32(i), expected: i32(i) };
- });
- },
- f32: () => {
- return fullF32Range().map((f) => {
- // Handles zeros and subnormals
- if (Math.abs(f) < 1.0) {
- return { input: f32(f), expected: i32(0) };
- }
-
- if (f <= kValue.i32.negative.min) {
- return { input: f32(f), expected: i32(kValue.i32.negative.min) };
- }
-
- if (f >= kValue.i32.positive.max) {
- return { input: f32(f), expected: i32(kValue.i32.positive.max) };
- }
-
- // All f32 no larger than 2^24 has a precise interger part and a fractional part, just need
- // to trunc towards 0 for the result integer.
- if (Math.abs(f) <= 2 ** 24) {
- return { input: f32(f), expected: i32(Math.trunc(f)) };
- }
-
- // All f32s between 2 ** 24 and kValue.i32.negative.min/.positive.max are
- // integers, so in theory one could use them directly, expect that number
- // is actually f64 internally, so they need to be quantized to f32 first.
- // Cannot just use trunc here, since that might produce a i32 value that
- // is precise in f64, but not in f32.
- return { input: f32(f), expected: i32(quantizeToF32(f)) };
- });
- },
- f16: () => {
- // Note that finite f16 values are always in range of i32.
- return fullF16Range().map((f) => {
- // Handles zeros and subnormals
- if (Math.abs(f) < 1.0) {
- return { input: f16(f), expected: i32(0) };
- }
-
- // All f16 no larger than <= 2^12 has a precise interger part and a fractional part, just need
- // to trunc towards 0 for the result integer.
- if (Math.abs(f) <= 2 ** 12) {
- return { input: f16(f), expected: i32(Math.trunc(f)) };
- }
-
- // All f16s larger than 2 ** 12 are integers, so in theory one could use them directly, expect
- // that number is actually f64 internally, so they need to be quantized to f16 first.
- // Cannot just use trunc here, since that might produce a i32 value that is precise in f64,
- // but not in f16.
- return { input: f16(f), expected: i32(quantizeToF16(f)) };
- });
- }
-});
-
/** Generate a ShaderBuilder based on how the test case is to be vectorized */
function vectorizeToExpression(vectorize) {
return vectorize === undefined ? unary('i32') : unary(`vec${vectorize}<i32>`);
@@ -121,7 +31,7 @@ u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3,
).
fn(async (t) => {
const cases = await d.get('bool');
- await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeI32, t.params, cases);
+ await run(t, vectorizeToExpression(t.params.vectorize), [Type.bool], Type.i32, t.params, cases);
});
g.test('u32').
@@ -138,7 +48,7 @@ u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3,
).
fn(async (t) => {
const cases = await d.get('u32');
- await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeI32, t.params, cases);
+ await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.i32, t.params, cases);
});
g.test('i32').
@@ -155,7 +65,7 @@ u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3,
).
fn(async (t) => {
const cases = await d.get('i32');
- await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeI32, t.params, cases);
+ await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.i32, t.params, cases);
});
g.test('f32').
@@ -172,7 +82,7 @@ u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3,
).
fn(async (t) => {
const cases = await d.get('f32');
- await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeI32, t.params, cases);
+ await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.i32, t.params, cases);
});
g.test('f16').
@@ -192,5 +102,57 @@ beforeAllSubcases((t) => {
}).
fn(async (t) => {
const cases = await d.get('f16');
- await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeI32, t.params, cases);
+ await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.i32, t.params, cases);
+});
+
+g.test('abstract_int').
+specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function').
+desc(
+ `
+i32(e), where e is an AbstractInt
+
+Identity operation if e is in bounds for i32, otherwise shader creation error
+`
+).
+params((u) =>
+u.
+combine('inputSource', onlyConstInputSource).
+combine('vectorize', [undefined, 2, 3, 4])
+).
+fn(async (t) => {
+ const cases = await d.get('abstractInt');
+ await run(
+ t,
+ vectorizeToExpression(t.params.vectorize),
+ [Type.abstractInt],
+ Type.i32,
+ t.params,
+ cases
+ );
+});
+
+g.test('abstract_float').
+specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function').
+desc(
+ `
+i32(e), where e is an AbstractFloat
+
+e is converted to i32, rounding towards zero
+`
+).
+params((u) =>
+u.
+combine('inputSource', onlyConstInputSource).
+combine('vectorize', [undefined, 2, 3, 4])
+).
+fn(async (t) => {
+ const cases = await d.get('abstractFloat');
+ await run(
+ t,
+ vectorizeToExpression(t.params.vectorize),
+ [Type.abstractFloat],
+ Type.i32,
+ t.params,
+ cases
+ );
}); \ No newline at end of file