Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Jiawei-Shao
Copy link
Contributor

@Jiawei-Shao Jiawei-Shao commented Jan 2, 2020

This patch adds "readonly-storage-texture" and "writeonly-storage-texture" as new enums of
GPUBindingType.


Preview | Diff

@Jiawei-Shao
Copy link
Contributor Author

Jiawei-Shao commented Jan 2, 2020

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 Shading Language 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

@Kangz
Copy link
Contributor

Kangz commented Jan 6, 2020

Thanks for the investigation and comparison tables. It seems that the motivation for readonly-storage-texture is because in Vulkan they are declared with a different usage flag, and a different binding type.

An alternative is to not add this binding type. If we look at shader operation sampled-texture can do a superset of what readonly-storage-texture so maybe when implementing WebGPU on Vulkan we could just make all storage textures also sampled and use OpTexeFetch instead of OpImageRead.

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.

*"access::read_write" requires Metal 1.2 so we don't include it in this table.

Note that we want storage-texture to be usable as readonly texture in a shader. The constraint Metal gives us here is that the texture must be declared as "read only" or "write only" in the shader.

spec/index.bs Outdated
const GPUTextureUsageFlags SAMPLED = 0x04;
const GPUTextureUsageFlags STORAGE = 0x08;
const GPUTextureUsageFlags OUTPUT_ATTACHMENT = 0x10;
const GPUTextureUsageFlags READONLY_STORAGE = 0x10;
Copy link
Contributor

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

Copy link
Contributor

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 :)

Copy link
Contributor

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?

Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

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.

Copy link
Contributor

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...

Copy link
Contributor

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.

@Jiawei-Shao
Copy link
Contributor Author

Jiawei-Shao commented Jan 17, 2020

I find another issue with the Image Format declaration in OpTypeImage in Vulkan.
According to Vulkan SPEC:

  • If shaderStorageImageReadWithoutFormat is not enabled and an OpTypeImage has “Image Format” operand of Unknown, any variables created with the given type must be decorated with NonReadable.
  • If shaderStorageImageWriteWithoutFormat is not enabled and an OpTypeImage has “Image Format” operand of Unknown, any variables created with the given type must be decorated with NonWritable.
    So in my mind it means we must declare Image Format for OpTypeImage, or we cannot call either ImageRead or ImageWrite.

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 OpTypeImage) must be compatible with the image view’s format when shaderStorageImageReadWithoutFormat and shaderStorageImageWriteWithoutFormat features are not enabled. The image format compatibility rules are also listed in the SPEC.

Shall we add the "storage texture format" member in GPUBindGroupLayoutBinding for this requirement on Vulkan?

@kvark
Copy link
Contributor

kvark commented Jan 18, 2020

@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 textureComponentType and suggested "storage texture format" allow validating the program - binding compatibility at the pipeline creation, as opposed to the draw call time (when we know all the bound groups and the active pipeline).

(I can't make my mind on this yet, so leaving this comment without a proposal)

@Jiawei-Shao
Copy link
Contributor Author

@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 OpTypeImage object in the shader so we should validate it in WebGPU implementation.

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 textureComponentType any longer.

@kvark
Copy link
Contributor

kvark commented Jan 19, 2020

If we start asking the shader, we'll essentially sabotage the whole idea behind the BindGroupLayout. The point of it is declaring the contract between resources and shaders, up-front. Once you have the contract, you use it for both sides, and it guarantees that nothing bad happens at binding time within a pass. If we start querying the component type and texture format from the shader, we may end up with a bind group (created from the same bind group layout) to be incompatible with a pipeline.

@kainino0x
Copy link
Contributor

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).

@magcius
Copy link

magcius commented Jan 22, 2020

The D3D equivalent to shaderStorageImageWriteWithoutFormat is required for D3D11 support where they're known as "typed buffers" (or "texture buffers" in legacy parlance), so that explains why it's 100% penetration on desktop.

@Jiawei-Shao
Copy link
Contributor Author

Updated this PR to follow the latest decision:

  • no "STORAGE_READ" texture usage
  • "readonly" and "writeonly" binding type
  • "texture format" in bindings

Copy link
Contributor

@kvark kvark left a 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|
@Jiawei-Shao Jiawei-Shao force-pushed the add-readonly-storage-texture branch from 08ff387 to ed425b9 Compare February 14, 2020 05:37
@Jiawei-Shao Jiawei-Shao force-pushed the add-readonly-storage-texture branch from 4efd1c7 to b2f7663 Compare February 14, 2020 05:55
@Jiawei-Shao Jiawei-Shao changed the title Add read-only storage textures as new binding type and texture usage Add read-only and write-only storage textures as new binding type Feb 18, 2020
@Jiawei-Shao Jiawei-Shao changed the title Add read-only and write-only storage textures as new binding type Add read-only and write-only storage textures as new binding types Feb 18, 2020
@Jiawei-Shao
Copy link
Contributor Author

PTAL, thanks!

@kvark kvark requested a review from JusSn February 20, 2020 14:45
spec/index.bs Outdated
GPUTextureComponentType textureComponentType = "float";
boolean multisampled = false;
boolean hasDynamicOffset = false;
GPUTextureFormat storageTextureFormat = {};
Copy link
Contributor

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?

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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 :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK with me!

Copy link
Contributor Author

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 = {};
Copy link
Contributor

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).

Copy link
Contributor Author

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 = {};
Copy link
Contributor

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.

@Kangz
Copy link
Contributor

Kangz commented Feb 24, 2020

I'd like to discuss the textureComponentType changes in more detail. Can we rollback changes there so we can land this PR and start another PR or issue to discuss changes to textureComponentType with the group and whether the default should be removed?

@Jiawei-Shao
Copy link
Contributor Author

@Kangz I've reverted all the changes with textureComponentType in this PR. PTAL, thanks!

@Jiawei-Shao
Copy link
Contributor Author

@JusSn PTAL, thanks!

@kvark kvark requested a review from JusSn March 2, 2020 20:51
@JusSn JusSn merged commit 31005ac into gpuweb:master Mar 2, 2020
JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Jun 8, 2020
…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
JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Jun 8, 2020
…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
@kdashg kdashg mentioned this pull request Jun 24, 2020
ben-clayton pushed a commit to ben-clayton/gpuweb that referenced this pull request Sep 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants