-
Notifications
You must be signed in to change notification settings - Fork 335
Add read-only and write-only storage textures as new binding types #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The following table lists the supports of the texture operations on every WebGPU texture binding type.
*Currently we cannot support read-write textures in WebGPU core SPEC because this feature requires Metal 1.2. The following table lists the correspondences of the WebGPU texture binding types in D3D12, Metal and Vulkan.
*"access::read_write" requires Metal 1.2 so we don't include it in this table. The following table lists the required texture usage for every binding type.
The following table lists the correspondences of the WebGPU texture usages in D3D12, Metal and Vulkan
|
Thanks for the investigation and comparison tables. It seems that the motivation for An alternative is to not add this binding type. If we look at shader operation I'm not sure which one is best: adding the readonly usage adds a bit more complexity to the API, but the alternative adds more usage flags in Vulkan implementations and might make shaders use a different HW path.
Note that we want |
spec/index.bs
Outdated
const GPUTextureUsageFlags SAMPLED = 0x04; | ||
const GPUTextureUsageFlags STORAGE = 0x08; | ||
const GPUTextureUsageFlags OUTPUT_ATTACHMENT = 0x10; | ||
const GPUTextureUsageFlags READONLY_STORAGE = 0x10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this usage is needed: see #541
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, you don't see that this is needed?
confused because you are pointing to the issue saying that it is needed :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following discussions in the meeting, can we land this PR and discuss readonly usage flags for buffers and textures in a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editors concluded to slightly prefer STORAGE_READ
name, other than that we can land
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have STORAGE_READ
should we not have STORAGE = 0x18
?
If we decide there's no chance of adding a STORAGE_WRITE
later (TBD), I'd prefer READONLY_STORAGE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AH right, thanks for the clarification. My take was that STORAGE_READ
is just more consistent with other usage names and future-proof for the case where we want to have STORAGE_WRITE
. I didn't realize you have a strong preference to READONLY_STORAGE
, this would mean we have to resolve the write-only conversation first before proceeding with this one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, mainly would prefer READONLY_STORAGE
if we end up with "readonly-storage-binding"
, for consistency.
I find another issue with the
Vulkan SPEC also defines the SPIR-V image formats compatibility rules with the Vulkan image formats. The SPEC says, the SPIR-V Image Format (the Image Format of Shall we add the "storage texture format" member in |
@Jiawei-Shao the table in Vulkan spec that you list to has only 1:1 correspondence between the Vulkan formats and SPIR-V formats. So are you basically suggesting that we add the texture format to the bind group layout? On the plus side, that would allow us to validate at pipeline creation time that the shader is using the proper format to access an image. However, it would put a restriction on the user (unable to use the same layout for different formats and shaders) that is otherwise unnecessary. Notably, bind group layout already has textureComponentType, which, if I'm not mistaken, was introduced in #384 for a very similar reason It appears to me that both the component type and the format would need to be considered together. To make this clear: both (I can't make my mind on this yet, so leaving this comment without a proposal) |
@kvark yes I am suggesting that we add the texture format to the bind group layout because I find Vulkan requires the format of the image view be compatible with the related Another choice can be that we just do the validation with the information fetched from the declarations in the shader directly. Note that if we take this strategy everywhere in WebGPU SPEC, I don't think we need |
If we start asking the shader, we'll essentially sabotage the whole idea behind the |
Interestingly, desktop support for shaderStorageImageWriteWithoutFormat is nearly 100% (though only recent android gpus (e.g. adreno 5xx+)), while shaderStorageImageReadWithoutFormat is much lower (65% of gpuinfo.org reports on desktop, lower on mobile). |
The D3D equivalent to |
Updated this PR to follow the latest decision:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
This patch adds "readonly-storage-texture" as a new enum of GPUBindingType and "READONLY_STORAGE" as a new enum of GPUTextureUsage. The following table lists the supports of the texture operations on every WebGPU texture binding type. For simplicity purposes, we are using SPIR-V operations in this table. |WebGPU Binding Type |Operations with Sampler(including OpImageFetch)|OpImageRead |OpImageWrite | |------------------------|-----------------------------------------------|--------------|-------------| |sampled-texture |Supported |Not supported |Not supported| |storage-texture |Not Supported |Not Supported*|Supported | |readonly-storage-texture|Not Supported |Supported |Not Supported| *Currently we cannot support read-write textures in WebGPU core SPEC because this feature requires Metal 1.2. The following table lists the correspondences of the WebGPU texture binding types in D3D12, Metal and Vulkan. |WebGPU Binding Type |D3D12(HLSL) |D3D12(descriptor range type) | Metal |Vulkan(SPIR-V)|Vulkan (VkDescriptorType) | |------------------------|------------|-------------------------------|--------------|--------------|--------------------------------| |sampled-texture |Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::sample|Sampled == 1 |VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE| |storage-texture |RWTexture2D |D3D12_DESCRIPTOR_RANGE_TYPE_UAV|access::write*|Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| |readonly-storage-texture|Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::read |Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| *"access::read_write" requires Metal 1.2 so we don't include it in this table. The following table lists the required texture usage for every binding type. |WebGPU Binding Type |WebGPU Texture Usage| |------------------------|--------------------| |sampled-texture |SAMPLED | |storage-texture |STORAGE | |readonly-storage-texture|READONLY_STORAGE | The following table lists the correspondences of the WebGPU texture usages in D3D12, Metal and Vulkan |WebGPU Binding Type |D3D12 |Metal |Vulkan | |------------------------|-------------------------------------------|--------------------------|--------------------------| |sampled-texture | |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_SAMPLED_BIT| |storage-texture |D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |MTLTextureUsageShaderWrite|VK_IMAGE_USAGE_STORAGE_BIT| |readonly-storage-texture| |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_STORAGE_BIT|
08ff387
to
ed425b9
Compare
4efd1c7
to
b2f7663
Compare
PTAL, thanks! |
spec/index.bs
Outdated
GPUTextureComponentType textureComponentType = "float"; | ||
boolean multisampled = false; | ||
boolean hasDynamicOffset = false; | ||
GPUTextureFormat storageTextureFormat = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it an error if storageTextureFormat
doesn't match textureComponentType
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact textureComponentType
is not needed when storageTextureFormat
is specified. Should I mention it clearly here?
Also should I add all the texture formats that are supported as writable storage texture here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately it's not possible right now for textureComponentType
to have no value. If it is not specified, then it will be "float"
.
We could remove that default (so it defaults to "not set") and put spec text that says "if it's a sampled texture and textureComponentType
is not set, textureComponentType defaults to "float"
".
We really want to define an algebraic data type (/tagged union) here, but we have to work within the bounds of WebIDL. I think that's probably the best way to do it, unless WebIDL allows GPUBindGroupLayoutDescriptor to take bindings
as a sequence of (GPUBindGroupSampledTextureBinding or GPUBindGroupStorageTextureBinding or ...)
(which would be indistinguishable at the JS level except by the value of type
). I don't think it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to require the user to set textureComponentType
explicitly for the sampled textures and storageTextureFormat
for the storage ones. Defaulting to "float" wasn't something I was happy about :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK with me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the latest PR, I've removed the default value of textureComponentType
. I have also renamed textureComponentType
to sampledTextureComponentType
to indicate it is only related to sampled textures.
spec/index.bs
Outdated
GPUTextureComponentType textureComponentType = "float"; | ||
boolean multisampled = false; | ||
boolean hasDynamicOffset = false; | ||
GPUTextureFormat storageTextureFormat = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value {}
is only for dictionaries. You don't need to provide a default value; then the default value will be "not set" (undefined
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
spec/index.bs
Outdated
GPUTextureComponentType textureComponentType = "float"; | ||
boolean multisampled = false; | ||
boolean hasDynamicOffset = false; | ||
GPUTextureFormat storageTextureFormat = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately it's not possible right now for textureComponentType
to have no value. If it is not specified, then it will be "float"
.
We could remove that default (so it defaults to "not set") and put spec text that says "if it's a sampled texture and textureComponentType
is not set, textureComponentType defaults to "float"
".
We really want to define an algebraic data type (/tagged union) here, but we have to work within the bounds of WebIDL. I think that's probably the best way to do it, unless WebIDL allows GPUBindGroupLayoutDescriptor to take bindings
as a sequence of (GPUBindGroupSampledTextureBinding or GPUBindGroupStorageTextureBinding or ...)
(which would be indistinguishable at the JS level except by the value of type
). I don't think it does.
I'd like to discuss the |
@Kangz I've reverted all the changes with |
@JusSn PTAL, thanks! |
…puweb#532) * Add read-only storage textures as new binding type and texture usage This patch adds "readonly-storage-texture" as a new enum of GPUBindingType and "READONLY_STORAGE" as a new enum of GPUTextureUsage. The following table lists the supports of the texture operations on every WebGPU texture binding type. For simplicity purposes, we are using SPIR-V operations in this table. |WebGPU Binding Type |Operations with Sampler(including OpImageFetch)|OpImageRead |OpImageWrite | |------------------------|-----------------------------------------------|--------------|-------------| |sampled-texture |Supported |Not supported |Not supported| |storage-texture |Not Supported |Not Supported*|Supported | |readonly-storage-texture|Not Supported |Supported |Not Supported| *Currently we cannot support read-write textures in WebGPU core SPEC because this feature requires Metal 1.2. The following table lists the correspondences of the WebGPU texture binding types in D3D12, Metal and Vulkan. |WebGPU Binding Type |D3D12(HLSL) |D3D12(descriptor range type) | Metal |Vulkan(SPIR-V)|Vulkan (VkDescriptorType) | |------------------------|------------|-------------------------------|--------------|--------------|--------------------------------| |sampled-texture |Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::sample|Sampled == 1 |VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE| |storage-texture |RWTexture2D |D3D12_DESCRIPTOR_RANGE_TYPE_UAV|access::write*|Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| |readonly-storage-texture|Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::read |Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| *"access::read_write" requires Metal 1.2 so we don't include it in this table. The following table lists the required texture usage for every binding type. |WebGPU Binding Type |WebGPU Texture Usage| |------------------------|--------------------| |sampled-texture |SAMPLED | |storage-texture |STORAGE | |readonly-storage-texture|READONLY_STORAGE | The following table lists the correspondences of the WebGPU texture usages in D3D12, Metal and Vulkan |WebGPU Binding Type |D3D12 |Metal |Vulkan | |------------------------|-------------------------------------------|--------------------------|--------------------------| |sampled-texture | |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_SAMPLED_BIT| |storage-texture |D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |MTLTextureUsageShaderWrite|VK_IMAGE_USAGE_STORAGE_BIT| |readonly-storage-texture| |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_STORAGE_BIT| * Use "STORAGE_READ" * Add storageTextureFormat * Only keep "STORAGE" usage and add "writeonly-storage-texture" binding type * Remove all GPUBindingType/storage-texture and update SPEC * Add missing check on GPUBindGroupBinding/storageTextureFormat * Rename textureComponentType to sampledTextureComponentType * Revert "Rename textureComponentType to sampledTextureComponentType" This reverts commit 0e6f4af. * Remove the default value of storageTextureFormat
…puweb#532) * Add read-only storage textures as new binding type and texture usage This patch adds "readonly-storage-texture" as a new enum of GPUBindingType and "READONLY_STORAGE" as a new enum of GPUTextureUsage. The following table lists the supports of the texture operations on every WebGPU texture binding type. For simplicity purposes, we are using SPIR-V operations in this table. |WebGPU Binding Type |Operations with Sampler(including OpImageFetch)|OpImageRead |OpImageWrite | |------------------------|-----------------------------------------------|--------------|-------------| |sampled-texture |Supported |Not supported |Not supported| |storage-texture |Not Supported |Not Supported*|Supported | |readonly-storage-texture|Not Supported |Supported |Not Supported| *Currently we cannot support read-write textures in WebGPU core SPEC because this feature requires Metal 1.2. The following table lists the correspondences of the WebGPU texture binding types in D3D12, Metal and Vulkan. |WebGPU Binding Type |D3D12(HLSL) |D3D12(descriptor range type) | Metal |Vulkan(SPIR-V)|Vulkan (VkDescriptorType) | |------------------------|------------|-------------------------------|--------------|--------------|--------------------------------| |sampled-texture |Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::sample|Sampled == 1 |VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE| |storage-texture |RWTexture2D |D3D12_DESCRIPTOR_RANGE_TYPE_UAV|access::write*|Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| |readonly-storage-texture|Texture2D |D3D12_DESCRIPTOR_RANGE_TYPE_SRV|access::read |Sampled == 2 |VK_DESCRIPTOR_TYPE_STORAGE_IMAGE| *"access::read_write" requires Metal 1.2 so we don't include it in this table. The following table lists the required texture usage for every binding type. |WebGPU Binding Type |WebGPU Texture Usage| |------------------------|--------------------| |sampled-texture |SAMPLED | |storage-texture |STORAGE | |readonly-storage-texture|READONLY_STORAGE | The following table lists the correspondences of the WebGPU texture usages in D3D12, Metal and Vulkan |WebGPU Binding Type |D3D12 |Metal |Vulkan | |------------------------|-------------------------------------------|--------------------------|--------------------------| |sampled-texture | |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_SAMPLED_BIT| |storage-texture |D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |MTLTextureUsageShaderWrite|VK_IMAGE_USAGE_STORAGE_BIT| |readonly-storage-texture| |MTLTextureUsageShaderRead |VK_IMAGE_USAGE_STORAGE_BIT| * Use "STORAGE_READ" * Add storageTextureFormat * Only keep "STORAGE" usage and add "writeonly-storage-texture" binding type * Remove all GPUBindingType/storage-texture and update SPEC * Add missing check on GPUBindGroupBinding/storageTextureFormat * Rename textureComponentType to sampledTextureComponentType * Revert "Rename textureComponentType to sampledTextureComponentType" This reverts commit 0e6f4af. * Remove the default value of storageTextureFormat
This patch adds "readonly-storage-texture" and "writeonly-storage-texture" as new enums of
GPUBindingType.
Preview | Diff