-
Notifications
You must be signed in to change notification settings - Fork 345
Description
Texture dimension types and texture view dimension types are different. When we create a texture view with a specific dimension type, which texture dimension type is valid? For example, whether we can create a 2D Array texture view upon a 3D texture and vice versa? This investigation attempts to get a conclusion for this question.
Question
In WebGPU, texture dimensions include 1d, 2d, 3d. If the dimension is 2d and size.depth is greater than 1, it is actually a 2d-array texture. So there are actually 4 texture dimension types. While texture view dimensions include 1d, 2d, 2d-array, cube, cube-array, 3d. Texture and TextureView dimension types are different. There is no obvious bijection between them. So the question is: when we create a texture view with a given dimension type, which texture dimension type is valid (Y or N)? I try to answer this question (by my institution) below:
| TextureView Dimension Type | 1d Texture | 2d Texture | 2d-array Texture* | 3d Texture |
|---|---|---|---|---|
| 1d TextureView | Y | N | N | N |
| 2d TextureView | N | Y | Y? | Y? |
| 2d-array TextureView | N | Y? | Y | ? |
| cube TextureView | N | N | Y* | ? |
| cube-array TextureView | N | N | Y* | ? |
| 3d TextureView | N | N? | ? | Y |
Notes:
- cube and cube-array TextureViews can be created upon 2d-array textures with a few more requirements like width equals to height, and its corresponding texture's array layers should be greater than 6 or multiple of 6, and so on. So I marked
Y*for cube and cube-array TextureView upon 2d-array texture. - cube and cube-array TextureViews can be seen as special 2d-array texture views. So I marked
?for 2d-array, cube, and cube-array TextureView upon 3d texture. I also marked?for 3d TextureView upon 2d-array texture.
So the most important question is: whether we can create 2d-array texture view upon a 3D texture and vice versa. Another question is we need to make sure whether 2d view can be created upon 2d-array/3d texture and vice versa.
Investigation about native graphics
Vulkan
Vulkan exposes a flag named VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT via VkImageCreateFlagBits in VkImageCreateInfo, in order to support 2d/2d-array texture view upon 3d texture, see Table 15. Image and image view parameter compatibility requirements under Image Views.
This flag is supported in Vulkan 1.1 core feature, and Vulkan 1.0 with extension VK_KHR_maintenance1
However, there is no flag which can support 3D texture view compatible upon 2d-array texture.
Metal
The concept of texture view in Metal is really weak. I can't even find objects like MTLTextureView or MTLTextureViewType for texture view. The only one we can use is MTLTexture and MTLTextureType. If we want to reinterpret a texture type into another texture type for some reason like reinterpret texture formats, reuse partial subresource, etc., we can call makeTextureView, which will return a new texture with the dimension types, formats, etc., you want.
On the description page of makeTextureView, a table describes the compatibility between the new texture dimension types and its original dimension types. Unfortunately, there is no way to create 2d-array texture (view) upon 3d texture or vice versa.
D3D12
I didn't find any related flag in D3D12_RESOURCE_FLAGS of D3D12_RESOURCE_DESC.
We can also look into the definition about resource view. Take D3D12_SHADER_RESOURCE_VIEW_DESC as an example:
typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC {
DXGI_FORMAT Format;
D3D12_SRV_DIMENSION ViewDimension;
UINT Shader4ComponentMapping;
union {
D3D12_BUFFER_SRV Buffer;
D3D12_TEX1D_SRV Texture1D;
D3D12_TEX1D_ARRAY_SRV Texture1DArray;
D3D12_TEX2D_SRV Texture2D;
D3D12_TEX2D_ARRAY_SRV Texture2DArray;
D3D12_TEX2DMS_SRV Texture2DMS;
D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray;
D3D12_TEX3D_SRV Texture3D;
D3D12_TEXCUBE_SRV TextureCube;
D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray;
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV RaytracingAccelerationStructure;
};
} D3D12_SHADER_RESOURCE_VIEW_DESC;
The explanation about ViewDimension is that A D3D12_SRV_DIMENSION-typed value that specifies the resource type of the view. This type is the same as the resource type of the underlying resource. This member also determines which _SRV to use in the union below.. This description of ViewDimension means that the resource view type should be exactly the same with its underlying resource. Moreover, definitions like D3D12_TEX3D_SRV and D3D12_TEX2D_ARRAY_SRV also assume the underlying resource is exactly a 3D texture and a 2d-array texture respectively.
Other resource views like D3D12_RENDER_TARGET_VIEW_DESC and D3D12_UNORDERED_ACCESS_VIEW_DESC are basically the same, although their union numbers are less than SRV's and their definitions like D3D12_TEX3D_RTV (no mipLevelCount because all RTV should be the same size) and D3D12_TEX2D_ARRAY_UAV might differ slightly from D3D12_TEX3D_SRV and D3D12_TEX2D_ARRAY_SRV.
Conclusion
- Now that we can't create 2d array texture view upon 3d texture and vice versa in Metal and D3D12, I think we should conclude that 2d-array (and cube/cube-array) texture view upon 3d texture and vice versa should be invalid in WebGPU.
- We can't create 2d texture view upon 3d texture in Metal and D3D12 (it is allowed in Vulkan with a flag), although we can create a 2d texture view upon 3d texture in theory (via specify the mip level and depth of a given 3d texture). Likewise, we can't create 2d texture view upon a 2d-array texture in D3D12 (It is allowed in Vulkan and Metal). We can look into D3D12_TEX2D_SRV. There is no parameter to set a particular arrayLayer, which means that it assume the underlying resource is a 2d texture, not a 2d-array texture. So we should conclude that 2d texture view upon 3d or 2d-array texture is not valid.
- We can create 2d-array texture view upon a 2d texture, because we can create 2d texture view upon a texture texture. And a 2d texture view can be seen as one-layer 2d-array texture view. But such a 2d-array texture view is useless. So 2d-array texture view upon 2d texture can be valid or invalid. I am neutral on this. Likewise, we can create 3d texture view where its depth=1 upon 2d texture, but it is nonsense and Metal doesn't allow texture reinterpret between 2d and 3d. So I think 3d texture view upon 2d texture doesn't make sense.
So my proposal about texture view dimension type compatibility with texture dimension type is listed as follows:
| TextureView Dimension Type | 1d Texture | 2d Texture | 2d-array Texture* | 3d Texture |
|---|---|---|---|---|
| 1d TextureView | Y | N | N | N |
| 2d TextureView | N | Y | N | N |
| 2d-array TextureView | N | Y/N | Y | N |
| cube TextureView | N | N | Y* | N |
| cube-array TextureView | N | N | Y* | N |
| 3d TextureView | N | N | N | Y |