Skip to content

Commit

Permalink
Add return type and texture type WGSL textureSample tests (gpuweb#3640)
Browse files Browse the repository at this point in the history
* Add return type and texture type WGSL textureSample tests
  • Loading branch information
greggman authored Apr 11, 2024
1 parent 5c8510e commit bee411b
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,8 @@
"webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument,non_const:*": { "subcaseMS": 1.604 },
"webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument:*": { "subcaseMS": 1.401 },
"webgpu:shader,validation,expression,call,builtin,textureSample:only_in_fragment:*": { "subcaseMS": 1.121 },
"webgpu:shader,validation,expression,call,builtin,textureSample:texture_type:*": { "subcaseMS": 1.888 },
"webgpu:shader,validation,expression,call,builtin,textureSample:return_type:*": { "subcaseMS": 1.888 },
"webgpu:shader,validation,expression,call,builtin,textureSampleBaseClampToEdge:coords_argument:*": { "subcaseMS": 239.356 },
"webgpu:shader,validation,expression,call,builtin,textureSampleBias:array_index_argument:*": { "subcaseMS": 1.630 },
"webgpu:shader,validation,expression,call,builtin,textureSampleBias:bias_argument:*": { "subcaseMS": 1.102 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,34 @@ export const kEntryPointsToValidateFragmentOnlyBuiltins = {
`,
},
};

export const kTestTextureTypes = [
'texture_1d<f32>',
'texture_1d<u32>',
'texture_2d<f32>',
'texture_2d<u32>',
'texture_2d_array<f32>',
'texture_2d_array<u32>',
'texture_3d<f32>',
'texture_3d<u32>',
'texture_cube<f32>',
'texture_cube<u32>',
'texture_cube_array<f32>',
'texture_cube_array<u32>',
'texture_multisampled_2d<f32>',
'texture_multisampled_2d<u32>',
'texture_depth_multisampled_2d',
'texture_external',
'texture_storage_1d<rgba8unorm, read>',
'texture_storage_1d<r32uint, read>',
'texture_storage_2d<rgba8unorm, read>',
'texture_storage_2d<r32uint, read>',
'texture_storage_2d_array<rgba8unorm, read>',
'texture_storage_2d_a32uint8unorm, read>',
'texture_storage_3d<rgba8unorm, read>',
'texture_storage_3d<r32uint, read>',
'texture_depth_2d',
'texture_depth_2d_array',
'texture_depth_cube',
'texture_depth_cube_array',
] as const;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Validation tests for the ${builtin}() builtin.
* test textureSample offset parameter must be a const-expression
* test textureSample offset parameter must be between -8 and +7 inclusive
* test textureSample not usable in a compute or vertex shader
* test textureSample returns the correct type
* test textureSample doesn't work with texture types it's not supposed to
note: uniformity validation is covered in src/webgpu/shader/validation/uniformity/uniformity.spec.ts
`;
Expand All @@ -25,40 +27,105 @@ import {
} from '../../../../../util/conversion.js';
import { ShaderValidationTest } from '../../../shader_validation_test.js';

import { kEntryPointsToValidateFragmentOnlyBuiltins } from './shader_stage_utils.js';
import {
kEntryPointsToValidateFragmentOnlyBuiltins,
kTestTextureTypes,
} from './shader_builtin_utils.js';

type TextureSampleArguments = {
returnType: ScalarType | VectorType;
coordsArgType: ScalarType | VectorType;
hasArrayIndexArg?: boolean;
offsetArgType?: VectorType;
};

const kValidTextureSampleParameterTypes: { [n: string]: TextureSampleArguments } = {
'texture_1d<f32>': { coordsArgType: Type.f32 },
'texture_2d<f32>': { coordsArgType: Type.vec2f, offsetArgType: Type.vec2i },
'texture_1d<f32>': { returnType: Type.vec4f, coordsArgType: Type.f32 },
'texture_2d<f32>': {
returnType: Type.vec4f,
coordsArgType: Type.vec2f,
offsetArgType: Type.vec2i,
},
'texture_2d_array<f32>': {
returnType: Type.vec4f,
coordsArgType: Type.vec2f,
hasArrayIndexArg: true,
offsetArgType: Type.vec2i,
},
'texture_3d<f32>': { coordsArgType: Type.vec3f, offsetArgType: Type.vec3i },
'texture_cube<f32>': { coordsArgType: Type.vec3f },
'texture_cube_array<f32>': { coordsArgType: Type.vec3f, hasArrayIndexArg: true },
texture_depth_2d: { coordsArgType: Type.vec2f, offsetArgType: Type.vec2i },
'texture_3d<f32>': {
returnType: Type.vec4f,
coordsArgType: Type.vec3f,
offsetArgType: Type.vec3i,
},
'texture_cube<f32>': { returnType: Type.vec4f, coordsArgType: Type.vec3f },
'texture_cube_array<f32>': {
returnType: Type.vec4f,
coordsArgType: Type.vec3f,
hasArrayIndexArg: true,
},
texture_depth_2d: { returnType: Type.f32, coordsArgType: Type.vec2f, offsetArgType: Type.vec2i },
texture_depth_2d_array: {
returnType: Type.f32,
coordsArgType: Type.vec2f,
hasArrayIndexArg: true,
offsetArgType: Type.vec2i,
},
texture_depth_cube: { coordsArgType: Type.vec3f },
texture_depth_cube_array: { coordsArgType: Type.vec3f, hasArrayIndexArg: true },
texture_depth_cube: { returnType: Type.f32, coordsArgType: Type.vec3f },
texture_depth_cube_array: {
returnType: Type.f32,
coordsArgType: Type.vec3f,
hasArrayIndexArg: true,
},
} as const;

const kTextureTypes = keysOf(kValidTextureSampleParameterTypes);
const kValuesTypes = objectsToRecord(kAllScalarsAndVectors);

export const g = makeTestGroup(ShaderValidationTest);

g.test('return_type')
.specURL('https://gpuweb.github.io/gpuweb/wgsl/#texturesample')
.desc(
`
Validates the return type of ${builtin} is the expected type.
`
)
.params(u =>
u
.combine('returnType', keysOf(kValuesTypes))
.combine('textureType', keysOf(kValidTextureSampleParameterTypes))
.beginSubcases()
.expand('offset', t =>
kValidTextureSampleParameterTypes[t.textureType].offsetArgType ? [false, true] : [false]
)
)
.fn(t => {
const { returnType, textureType, offset } = t.params;
const returnVarType = kValuesTypes[returnType];
const {
returnType: returnExpectedType,
offsetArgType,
coordsArgType,
hasArrayIndexArg,
} = kValidTextureSampleParameterTypes[textureType];

const varWGSL = returnVarType.toString();
const coordWGSL = coordsArgType.create(0).wgsl();
const arrayWGSL = hasArrayIndexArg ? ', 0' : '';
const offsetWGSL = offset ? `, ${offsetArgType?.create(0).wgsl()}` : '';

const code = `
@group(0) @binding(0) var s: sampler;
@group(0) @binding(1) var t: ${textureType};
@fragment fn fs() -> @location(0) vec4f {
let v: ${varWGSL} = textureSample(t, s, ${coordWGSL}${arrayWGSL}${offsetWGSL});
return vec4f(0);
}
`;
const expectSuccess = isConvertible(returnExpectedType, returnVarType);
t.expectCompileResult(expectSuccess, code);
});

g.test('coords_argument')
.specURL('https://gpuweb.github.io/gpuweb/wgsl/#texturesample')
.desc(
Expand Down Expand Up @@ -265,3 +332,47 @@ fn foo() {
}`;
t.expectCompileResult(config.expectSuccess, code);
});

g.test('texture_type')
.specURL('https://gpuweb.github.io/gpuweb/wgsl/#texturesample')
.desc(
`
Validates that incompatible texture types don't work with ${builtin}
`
)
.params(u =>
u
.combine('testTextureType', kTestTextureTypes)
.combine('textureType', keysOf(kValidTextureSampleParameterTypes))
.expand('offset', t =>
kValidTextureSampleParameterTypes[t.textureType].offsetArgType ? [false, true] : [false]
)
)
.fn(t => {
const { testTextureType, textureType, offset } = t.params;
const { coordsArgType, offsetArgType, hasArrayIndexArg } =
kValidTextureSampleParameterTypes[textureType];

const coordWGSL = coordsArgType.create(0).wgsl();
const arrayWGSL = hasArrayIndexArg ? ', 0' : '';
const offsetWGSL = offset ? `, ${offsetArgType?.create(0).wgsl()}` : '';

const code = `
@group(0) @binding(0) var s: sampler;
@group(0) @binding(1) var t: ${testTextureType};
@fragment fn fs() -> @location(0) vec4f {
let v = textureSample(t, s, ${coordWGSL}${arrayWGSL}${offsetWGSL});
return vec4f(0);
}
`;

const types = kValidTextureSampleParameterTypes[testTextureType];
const typesMatch = types
? types.coordsArgType === coordsArgType &&
types.hasArrayIndexArg === hasArrayIndexArg &&
(offset ? types.offsetArgType === offsetArgType : true)
: false;

const expectSuccess = testTextureType === textureType || typesMatch;
t.expectCompileResult(expectSuccess, code);
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from '../../../../../util/conversion.js';
import { ShaderValidationTest } from '../../../shader_validation_test.js';

import { kEntryPointsToValidateFragmentOnlyBuiltins } from './shader_stage_utils.js';
import { kEntryPointsToValidateFragmentOnlyBuiltins } from './shader_builtin_utils.js';

type TextureSampleBiasArguments = {
coordsArgType: ScalarType | VectorType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
} from '../../../../../util/conversion.js';
import { ShaderValidationTest } from '../../../shader_validation_test.js';

import { kEntryPointsToValidateFragmentOnlyBuiltins } from './shader_stage_utils.js';
import { kEntryPointsToValidateFragmentOnlyBuiltins } from './shader_builtin_utils.js';

type TextureSampleCompareArguments = {
coordsArgType: ScalarType | VectorType;
Expand Down
9 changes: 6 additions & 3 deletions src/webgpu/shader/validation/shader_validation_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ export class ShaderValidationTest extends GPUTest {
const compilationInfo = await shaderModule!.getCompilationInfo();

// MAINTENANCE_TODO: Pretty-print error messages with source context.
const messagesLog = compilationInfo.messages
.map(m => `${m.lineNum}:${m.linePos}: ${m.type}: ${m.message}`)
.join('\n');
const messagesLog =
compilationInfo.messages
.map(m => `${m.lineNum}:${m.linePos}: ${m.type}: ${m.message}`)
.join('\n') +
'\n\n---- shader ----\n' +
code;
error.extra.compilationInfo = compilationInfo;

if (compilationInfo.messages.some(m => m.type === 'error')) {
Expand Down

0 comments on commit bee411b

Please sign in to comment.