@@ -237,6 +237,34 @@ class TextureUsageTracking extends ValidationTest {
237237 pass . setPipeline ( pipeline ) ;
238238 pass . dispatchWorkgroups ( 1 ) ;
239239 }
240+
241+ skipIfNeedStorageTexturesByVisibilityAndNoStorageTextures ( visibility : number ) {
242+ if ( ! this . isCompatibility ) {
243+ return ;
244+ }
245+
246+ this . skipIf (
247+ ( visibility & GPUConst . ShaderStage . VERTEX ) !== 0 &&
248+ ! ( this . device . limits . maxStorageTexturesInVertexStage ! >= 2 ) ,
249+ `maxStorageTexturesInVertexStage(${ this . device . limits . maxStorageTexturesInVertexStage } ) < 2`
250+ ) ;
251+
252+ this . skipIf (
253+ ( visibility & GPUConst . ShaderStage . FRAGMENT ) !== 0 &&
254+ ! ( this . device . limits . maxStorageTexturesInFragmentStage ! >= 2 ) ,
255+ `maxStorageTexturesInFragmentStage(${ this . device . limits . maxStorageTexturesInFragmentStage } ) < 2`
256+ ) ;
257+ }
258+
259+ skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( s : string , visibility : number ) {
260+ if (
261+ s === 'readonly-storage-texture' ||
262+ s === 'writeonly-storage-texture' ||
263+ s === 'readwrite-storage-texture'
264+ ) {
265+ this . skipIfNeedStorageTexturesByVisibilityAndNoStorageTextures ( visibility ) ;
266+ }
267+ }
240268}
241269
242270export const g = makeTestGroup ( MaxLimitsTestMixin ( TextureUsageTracking ) ) ;
@@ -867,6 +895,8 @@ g.test('shader_stages_and_visibility,storage_write')
867895 secondUseConflicts,
868896 } = t . params ;
869897
898+ t . skipIfNeedStorageTexturesByVisibilityAndNoStorageTextures ( readVisibility | writeVisibility ) ;
899+
870900 const usage = GPUTextureUsage . TEXTURE_BINDING | GPUTextureUsage . STORAGE_BINDING ;
871901 const view = t . createTestTexture ( { usage } ) . createView ( ) ;
872902 const view2 = secondUseConflicts ? view : t . createTestTexture ( { usage } ) . createView ( ) ;
@@ -940,6 +970,8 @@ g.test('shader_stages_and_visibility,attachment_write')
940970 . fn ( t => {
941971 const { readVisibility, readEntry, secondUseConflicts } = t . params ;
942972
973+ t . skipIfNeedStorageTexturesByVisibilityAndNoStorageTextures ( readVisibility ) ;
974+
943975 const usage =
944976 GPUTextureUsage . TEXTURE_BINDING |
945977 GPUTextureUsage . RENDER_ATTACHMENT |
@@ -992,6 +1024,8 @@ g.test('replaced_binding')
9921024 . fn ( t => {
9931025 const { compute, callDrawOrDispatch, entry } = t . params ;
9941026
1027+ t . skipIfNeedStorageTexturesByVisibilityAndNoStorageTextures ( GPUShaderStage . FRAGMENT ) ;
1028+
9951029 const sampledView = t . createTestTexture ( ) . createView ( ) ;
9961030 const sampledStorageView = t
9971031 . createTestTexture ( {
@@ -1120,6 +1154,9 @@ g.test('bindings_in_bundle')
11201154 const { binding0InBundle, binding1InBundle, type0, type1, _usage0, _usage1, _sampleCount } =
11211155 t . params ;
11221156
1157+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( type0 , GPUShaderStage . FRAGMENT ) ;
1158+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( type1 , GPUShaderStage . FRAGMENT ) ;
1159+
11231160 // Two bindings are attached to the same texture view.
11241161 const usage =
11251162 _sampleCount === 4
@@ -1238,6 +1275,15 @@ g.test('unused_bindings_in_pipeline')
12381275 t . skipIfLanguageFeatureNotSupported ( 'readonly_and_readwrite_storage_textures' ) ;
12391276 }
12401277
1278+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures (
1279+ readOnlyUsage ,
1280+ GPUShaderStage . FRAGMENT
1281+ ) ;
1282+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures (
1283+ writableUsage ,
1284+ GPUShaderStage . FRAGMENT
1285+ ) ;
1286+
12411287 const view = t
12421288 . createTestTexture ( {
12431289 usage : GPUTextureUsage . TEXTURE_BINDING | GPUTextureUsage . STORAGE_BINDING ,
@@ -1371,6 +1417,9 @@ g.test('scope,dispatch')
13711417 . fn ( t => {
13721418 const { dispatch, usage1, usage2, setBindGroup0, setBindGroup1 } = t . params ;
13731419
1420+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage1 , GPUShaderStage . FRAGMENT ) ;
1421+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage2 , GPUShaderStage . FRAGMENT ) ;
1422+
13741423 const { bindGroup0, bindGroup1, encoder, pass, pipeline } = t . testValidationScope (
13751424 true ,
13761425 usage1 ,
@@ -1427,13 +1476,11 @@ g.test('scope,basic,render')
14271476 )
14281477 )
14291478 . fn ( t => {
1430- t . skipIf (
1431- t . isCompatibility && ! ( t . device . limits . maxStorageTexturesInFragmentStage ! >= 2 ) ,
1432- `maxStorageTexturesInFragmentStage(${ t . device . limits . maxStorageTexturesInFragmentStage } ) < 2`
1433- ) ;
1434-
14351479 const { setBindGroup0, setBindGroup1, usage1, usage2 } = t . params ;
14361480
1481+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage1 , GPUShaderStage . FRAGMENT ) ;
1482+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage2 , GPUShaderStage . FRAGMENT ) ;
1483+
14371484 const { bindGroup0, bindGroup1, encoder, pass } = t . testValidationScope ( false , usage1 , usage2 ) ;
14381485 assert ( pass instanceof GPURenderPassEncoder ) ;
14391486
@@ -1469,6 +1516,9 @@ g.test('scope,pass_boundary,compute')
14691516 . fn ( t => {
14701517 const { splitPass, usage1, usage2 } = t . params ;
14711518
1519+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage1 , GPUShaderStage . FRAGMENT ) ;
1520+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage2 , GPUShaderStage . FRAGMENT ) ;
1521+
14721522 const { bindGroupLayouts, bindGroups } = t . makeTwoBindGroupsWithOneTextureView ( usage1 , usage2 ) ;
14731523
14741524 const encoder = t . device . createCommandEncoder ( ) ;
@@ -1524,13 +1574,11 @@ g.test('scope,pass_boundary,render')
15241574 )
15251575 )
15261576 . fn ( t => {
1527- t . skipIf (
1528- t . isCompatibility && ! ( t . device . limits . maxStorageTexturesInFragmentStage ! >= 2 ) ,
1529- `maxStorageTexturesInFragmentStage(${ t . device . limits . maxStorageTexturesInFragmentStage } ) < 2`
1530- ) ;
1531-
15321577 const { splitPass, draw, usage1, usage2 } = t . params ;
15331578
1579+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage1 , GPUShaderStage . FRAGMENT ) ;
1580+ t . skipIfNeedStorageTexturesByResourceTypeAndNoStorageTextures ( usage2 , GPUShaderStage . FRAGMENT ) ;
1581+
15341582 const { bindGroupLayouts, bindGroups } = t . makeTwoBindGroupsWithOneTextureView ( usage1 , usage2 ) ;
15351583
15361584 const encoder = t . device . createCommandEncoder ( ) ;
0 commit comments