@@ -10,5 +10,164 @@ TODO:
1010
1111import { makeTestGroup } from '../../../../common/framework/test_group.js' ;
1212import { GPUTest } from '../../../gpu_test.js' ;
13+ import { TexelView } from '../../../util/texture/texel_view.js' ;
14+ import { textureContentIsOKByT2B } from '../../../util/texture/texture_ok.js' ;
1315
14- export const g = makeTestGroup ( GPUTest ) ;
16+ class FilterModeTest extends GPUTest {
17+ createRenderPipelineForTest ( ) : GPURenderPipeline {
18+ return this . device . createRenderPipeline ( {
19+ layout : 'auto' ,
20+ vertex : {
21+ module : this . device . createShaderModule ( {
22+ code : `
23+ struct Outputs {
24+ @builtin(position) Position : vec4<f32>,
25+ @location(0) fragUV : vec2<f32>,
26+ };
27+
28+ @vertex fn main(
29+ @builtin(vertex_index) VertexIndex : u32) -> Outputs {
30+ var position : array<vec3<f32>, 6> = array<vec3<f32>, 6>(
31+ vec3<f32>(-0.5, 0.5, -0.5),
32+ vec3<f32>(0.5, 0.5, -0.5),
33+ vec3<f32>(-0.5, 0.5, 0.5),
34+ vec3<f32>(-0.5, 0.5, 0.5),
35+ vec3<f32>(0.5, 0.5, -0.5),
36+ vec3<f32>(0.5, 0.5, 0.5));
37+
38+ // uv is pre-scaled to mimic repeating tiled texture
39+ var uv : array<vec2<f32>, 6> = array<vec2<f32>, 6>(
40+ vec2<f32>(0.0, 0.0),
41+ vec2<f32>(1.0, 0.0),
42+ vec2<f32>(0.0, 50.0),
43+ vec2<f32>(0.0, 50.0),
44+ vec2<f32>(1.0, 0.0),
45+ vec2<f32>(1.0, 50.0));
46+
47+ // draw a slanted plane in a specific way
48+ let matrix : mat4x4<f32> = mat4x4<f32>(
49+ vec4<f32>(-1.7320507764816284, 1.8322050568049563e-16, -6.176817699518044e-17, -6.170640314703498e-17),
50+ vec4<f32>(-2.1211504944260596e-16, -1.496108889579773, 0.5043753981590271, 0.5038710236549377),
51+ vec4<f32>(0.0, -43.63650894165039, -43.232173919677734, -43.18894577026367),
52+ vec4<f32>(0.0, 21.693578720092773, 21.789791107177734, 21.86800193786621));
53+
54+ var output : Outputs;
55+ output.fragUV = uv[VertexIndex];
56+ output.Position = matrix * vec4<f32>(position[VertexIndex], 1.0);
57+ return output;
58+ }
59+ ` ,
60+ } ) ,
61+ entryPoint : 'main' ,
62+ } ,
63+ fragment : {
64+ module : this . device . createShaderModule ( {
65+ code : `
66+ @group(0) @binding(0) var sampler0 : sampler;
67+ @group(0) @binding(1) var texture0 : texture_2d<f32>;
68+
69+ @fragment fn main(
70+ @builtin(position) FragCoord : vec4<f32>,
71+ @location(0) fragUV: vec2<f32>)
72+ -> @location(0) vec4<f32> {
73+ return textureSample(texture0, sampler0, fragUV);
74+ }
75+ ` ,
76+ } ) ,
77+ entryPoint : 'main' ,
78+ targets : [ { format : 'rgba8unorm' } ] ,
79+ } ,
80+ primitive : { topology : 'triangle-list' } ,
81+ } ) ;
82+ }
83+
84+ createBindGroupForTest (
85+ layout : GPUBindGroupLayout ,
86+ textureView : GPUTextureView ,
87+ sampler : GPUSampler
88+ ) : GPUBindGroup {
89+ return this . device . createBindGroup ( {
90+ layout,
91+ entries : [
92+ { binding : 0 , resource : sampler } ,
93+ { binding : 1 , resource : textureView } ,
94+ ] ,
95+ } ) ;
96+ }
97+
98+ drawTriangle ( textureView : GPUTextureView , sampler : GPUSampler ) {
99+ const renderTargetFormat = 'rgba8unorm' ;
100+ const renderTarget = this . device . createTexture ( {
101+ format : renderTargetFormat ,
102+ size : { width : 2 , height : 2 , depthOrArrayLayers : 1 } ,
103+ usage : GPUTextureUsage . COPY_SRC | GPUTextureUsage . RENDER_ATTACHMENT ,
104+ } ) ;
105+
106+ const encoder = this . device . createCommandEncoder ( ) ;
107+ const pass = encoder . beginRenderPass ( {
108+ colorAttachments : [
109+ {
110+ view : renderTarget . createView ( ) ,
111+ storeOp : 'store' ,
112+ loadOp : 'load' ,
113+ } ,
114+ ] ,
115+ } ) ;
116+
117+ const testPipeline = this . createRenderPipelineForTest ( ) ;
118+ pass . setPipeline ( testPipeline ) ;
119+ pass . setBindGroup (
120+ 0 ,
121+ this . createBindGroupForTest ( testPipeline . getBindGroupLayout ( 0 ) , textureView , sampler )
122+ ) ;
123+ pass . draw ( 6 ) ;
124+
125+ pass . end ( ) ;
126+ this . device . queue . submit ( [ encoder . finish ( ) ] ) ;
127+
128+ const expColor = {
129+ R : 0 ,
130+ G : 0 ,
131+ B : 0 ,
132+ A : 0.0 ,
133+ } ;
134+ const expTexelView = TexelView . fromTexelsAsColors ( renderTargetFormat , coords => expColor ) ;
135+
136+ const result = textureContentIsOKByT2B (
137+ this ,
138+ { texture : renderTarget } ,
139+ [ 2 , 2 ] ,
140+ { expTexelView } ,
141+ { maxDiffULPsForNormFormat : 1 }
142+ ) ;
143+ this . eventualExpectOK ( result ) ;
144+ this . trackForCleanup ( renderTarget ) ;
145+ }
146+ }
147+
148+ export const g = makeTestGroup ( FilterModeTest ) ;
149+
150+ const kTextureFormat = 'rgba8unorm' ;
151+
152+ g . test ( 'filter_mode,minFilter' )
153+ . desc ( 'Test that stencil reference is initialized as zero for new render pass.' )
154+ . params ( u => u . combine ( 'magFilter' , [ 'nearest' , 'linear' ] as const ) )
155+ . fn ( async t => {
156+ const { magFilter } = t . params ;
157+
158+ const textureSize = 2 ;
159+ const texture = t . device . createTexture ( {
160+ mipLevelCount : 1 ,
161+ size : { width : textureSize , height : textureSize , depthOrArrayLayers : 1 } ,
162+ format : kTextureFormat ,
163+ usage : GPUTextureUsage . COPY_SRC | GPUTextureUsage . TEXTURE_BINDING ,
164+ } ) ;
165+
166+ const sampler = t . device . createSampler ( {
167+ magFilter,
168+ minFilter : 'linear' ,
169+ mipmapFilter : 'linear' ,
170+ } ) ;
171+
172+ t . drawTriangle ( texture . createView ( ) , sampler ) ;
173+ } ) ;
0 commit comments