-
Notifications
You must be signed in to change notification settings - Fork 345
Description
I was implementing these in Chrome. My first implementation counts resources by checking bindGroupLayouts when creating pipelines. I ran into this issue. In the CTS there is a test that creates a bindGroupLayout with a storage texture. It then uses that with a shader that doesn't access the texture.
Example:
// passes because even though this device supports 0 storageTextures in fragment shaders
// the proposal is the error happens at create pipeline time
const bindGroupLayout = device.createBindGroupLayout({
entries: [
{
binding: 0,
visibility: GPUShaderStage.FRAGMENT,
storageTexture: {
access: "read-only",
viewDimension: "2d",
format: "rgba8unorm",
},
},
],
});
// passes because even though this device supports 0 storageTextures in fragment shaders
// the proposal is the error happens at create pipeline time
const pipelineLayout = device.createPipelineLayout({
bindGroupLayouts: [ bindGroupLayout ],
});
// shader does not reference any resources
const module = device.createShaderModule({
code: `
@vertex fn vs() -> @builtin(position) vec4f { return vec4f(0); }
@fragment fn fs() -> @location(0) vec4f { return vec4f(0); }
`,
});
// failed in my impl because pipelineLayout uses a storage texture and device supports 0
const pipeline = device.createRenderPipeline({
layout: pipelineLayout,
vertex: { module },
fragment: { module, targets: [{ format: 'rgba8unorm' }] },
});Issue 1: This is different than the way maxStorage(Buffer/Texture)sPerShadeStage behaves
Change the code above so that it creates 5 storage texture bindings in createBindGroupLayout and it will get an error (5 > maxStorageTexturesPerShaderStage which is 4). Change the code above to make 2 bindGroupLayouts that each use 3 storage texture bindings. Those pass. Then try to create a pipelineLayout with both bindGroupLayouts. You'll get an error (6 > maxStorageTexturesPerShaderStage which is 4)
Issue 2: In both cases this is pessimizing (not sure that's the right word here)
Looking at the example code above, the shaders themselves don't actually use the resources so even though the "bindings" are past the limits the shaders aren't using them. You can't do this with maxStorageTexturesPerShaderStage because of the extra validation at createBindGroupLayout and createPipelineLayout
Question: Should we
-
make the validation for
maxStorage(Buffers/Textures)In(Vertex/Fragment)Stagesimilar to the validation formaxStorage(Buffer/Texture)sPerShadeStageso they are checked increateBindGroupLayoutandcreatePipelineLayout? -
relax both compat and core so it's valid to make bindGroupLayouts and pipelineLayouts with more than
maxStorage(Buffer/Texture)sPerShadeStagebut you only get the error when you actually try to create a pipeline? -
Same as (2) but relax even more that you don't get an error at create pipeline time if the shaders themselves don't use more resources than allowed. I assume this was discussed long ago and there's a reason it's the way it is but I thought I'd ask since this came up in the context of a shader like the one above that uses no resources but getting an error because its pipeline layout referenced too many of a certain type of resource.
-
Leave it as specified
maxStorage(Buffers/Textures)In(Vertex/Fragment)Stageare not checked atcreateBindGroupLayoutnorcreatePipelineLayout. -
other ideas...
What's the actual error
Further, If the choice is (4) there's the issue about what the actual error condition is. The current proposal for compat says simply:
If the number of shader variables of type
texture_storage_1d,texture_storage_2d,texture_storage_2d_arrayandtexture_storage_3din a fragment shader exceeds themaxStorageTexturesInFragmentStagelimit, a validation error will occur at pipeline creation time.
It does not spell out if this is what's in the pipeline layout or only what that shader actually uses.