Add basic supports of storage textures on Vulkan
This patch adds the basic supports of read-only and write-only storage textures on Vulkan. The subresource tracking and barriers on the subresources used as read-only and write-only storage textures are not included in this patch. BUG=dawn:267 TEST=dawn_end2end_tests Change-Id: I6831b96202a97182763ecd28bc41ab03df904a7c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20560 Commit-Queue: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
c85ef7927f
commit
754c161fd3
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "dawn_native/BindGroup.h"
|
||||
#include "dawn_native/BindGroupTracker.h"
|
||||
#include "dawn_native/Buffer.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
|
@ -34,8 +36,8 @@ namespace dawn_native {
|
|||
uint32_t dynamicOffsetCount,
|
||||
uint32_t* dynamicOffsets) {
|
||||
if (this->mBindGroups[index] != bindGroup) {
|
||||
mBuffers[index] = {};
|
||||
mBuffersNeedingBarrier[index] = {};
|
||||
mBindings[index] = {};
|
||||
mBindingsNeedingBarrier[index] = {};
|
||||
|
||||
const BindGroupLayoutBase* layout = bindGroup->GetLayout();
|
||||
|
||||
|
@ -58,16 +60,23 @@ namespace dawn_native {
|
|||
break;
|
||||
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
mBuffersNeedingBarrier[index].set(bindingIndex);
|
||||
mBuffers[index][bindingIndex] =
|
||||
bindGroup->GetBindingAsBufferBinding(bindingIndex).buffer;
|
||||
mBindingsNeedingBarrier[index].set(bindingIndex);
|
||||
mBindings[index][bindingIndex] = static_cast<ObjectBase*>(
|
||||
bindGroup->GetBindingAsBufferBinding(bindingIndex).buffer);
|
||||
break;
|
||||
|
||||
// Read-only and write-only storage textures must use general layout
|
||||
// because load and store operations on storage images can only be done on
|
||||
// the images in VK_IMAGE_LAYOUT_GENERAL layout.
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
mBindingsNeedingBarrier[index].set(bindingIndex);
|
||||
mBindings[index][bindingIndex] = static_cast<ObjectBase*>(
|
||||
bindGroup->GetBindingAsTextureView(bindingIndex));
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
// Not implemented.
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -79,10 +88,10 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
protected:
|
||||
std::array<std::bitset<kMaxBindingsPerGroup>, kMaxBindGroups> mBuffersNeedingBarrier = {};
|
||||
std::array<std::bitset<kMaxBindingsPerGroup>, kMaxBindGroups> mBindingsNeedingBarrier = {};
|
||||
std::array<std::array<wgpu::BindingType, kMaxBindingsPerGroup>, kMaxBindGroups>
|
||||
mBindingTypes = {};
|
||||
std::array<std::array<BufferBase*, kMaxBindingsPerGroup>, kMaxBindGroups> mBuffers = {};
|
||||
std::array<std::array<ObjectBase*, kMaxBindingsPerGroup>, kMaxBindGroups> mBindings = {};
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -148,11 +148,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
if (mInCompute) {
|
||||
for (uint32_t index : IterateBitSet(mBindGroupLayoutsMask)) {
|
||||
for (uint32_t binding : IterateBitSet(mBuffersNeedingBarrier[index])) {
|
||||
for (uint32_t binding : IterateBitSet(mBindingsNeedingBarrier[index])) {
|
||||
wgpu::BindingType bindingType = mBindingTypes[index][binding];
|
||||
switch (bindingType) {
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
ToBackend(mBuffers[index][binding])
|
||||
static_cast<Buffer*>(mBindings[index][binding])
|
||||
->TrackUsageAndTransitionNow(commandContext,
|
||||
wgpu::BufferUsage::Storage);
|
||||
break;
|
||||
|
|
|
@ -140,17 +140,24 @@ namespace dawn_native { namespace vulkan {
|
|||
mDynamicOffsetCounts, mDynamicOffsets);
|
||||
|
||||
for (uint32_t index : IterateBitSet(mBindGroupLayoutsMask)) {
|
||||
for (uint32_t bindingIndex : IterateBitSet(mBuffersNeedingBarrier[index])) {
|
||||
for (uint32_t bindingIndex : IterateBitSet(mBindingsNeedingBarrier[index])) {
|
||||
switch (mBindingTypes[index][bindingIndex]) {
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
ToBackend(mBuffers[index][bindingIndex])
|
||||
static_cast<Buffer*>(mBindings[index][bindingIndex])
|
||||
->TransitionUsageNow(recordingContext,
|
||||
wgpu::BufferUsage::Storage);
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
ToBackend(
|
||||
static_cast<TextureViewBase*>(mBindings[index][bindingIndex])
|
||||
->GetTexture())
|
||||
->TransitionUsageNow(recordingContext,
|
||||
wgpu::TextureUsage::Storage);
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
// Not implemented.
|
||||
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
|
|
|
@ -120,9 +120,11 @@ namespace dawn_native { namespace vulkan {
|
|||
// combination of GENERAL and TRANSFER_SRC_OPTIMAL. This would be a problem, so we
|
||||
// make CopySrc use GENERAL.
|
||||
case wgpu::TextureUsage::CopySrc:
|
||||
// Writable storage textures must use general. If we could know the texture is read
|
||||
// only we could use SHADER_READ_ONLY_OPTIMAL
|
||||
// Read-only and write-only storage textures must use general layout because load
|
||||
// and store operations on storage images can only be done on the images in
|
||||
// VK_IMAGE_LAYOUT_GENERAL layout.
|
||||
case wgpu::TextureUsage::Storage:
|
||||
case kReadonlyStorageTexture:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case wgpu::TextureUsage::OutputAttachment:
|
||||
if (format.HasDepthOrStencil()) {
|
||||
|
@ -149,11 +151,15 @@ namespace dawn_native { namespace vulkan {
|
|||
if (usage & (wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst)) {
|
||||
flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
if (usage & (wgpu::TextureUsage::Sampled | wgpu::TextureUsage::Storage)) {
|
||||
if (usage & (wgpu::TextureUsage::Sampled | kReadonlyStorageTexture)) {
|
||||
flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
}
|
||||
if (usage & wgpu::TextureUsage::Storage) {
|
||||
flags |=
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
}
|
||||
if (usage & wgpu::TextureUsage::OutputAttachment) {
|
||||
if (format.HasDepthOrStencil()) {
|
||||
flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
|
|
|
@ -176,6 +176,7 @@ class StorageTextureTests : public DawnTest {
|
|||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.f, 0.f, 0.f, 1.f);
|
||||
gl_PointSize = 1.0f;
|
||||
})";
|
||||
|
||||
const char* kCommonReadOnlyTestCode_uimage2D = R"(
|
||||
|
@ -236,8 +237,8 @@ TEST_P(StorageTextureTests, BindGroupLayoutWithStorageTextureBindingType) {
|
|||
|
||||
// Test that read-only storage textures are supported in compute shader.
|
||||
TEST_P(StorageTextureTests, ReadonlyStorageTextureInComputeShader) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12, Vulkan and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsVulkan() || IsOpenGL());
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
|
||||
|
||||
// Prepare the read-only storage texture and fill it with the expected data.
|
||||
// TODO(jiawei.shao@intel.com): test more texture formats.
|
||||
|
@ -291,8 +292,8 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInComputeShader) {
|
|||
|
||||
// Test that read-only storage textures are supported in vertex shader.
|
||||
TEST_P(StorageTextureTests, ReadonlyStorageTextureInVertexShader) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12, Vulkan and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsVulkan() || IsOpenGL());
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
|
||||
|
||||
// When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
|
||||
// read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
|
||||
|
@ -321,6 +322,7 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInVertexShader) {
|
|||
} else {
|
||||
o_color = vec4(1.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
gl_PointSize = 1.0f;
|
||||
})";
|
||||
const char* kFragmentShader = R"(
|
||||
#version 450
|
||||
|
@ -334,8 +336,8 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInVertexShader) {
|
|||
|
||||
// Test that read-only storage textures are supported in fragment shader.
|
||||
TEST_P(StorageTextureTests, ReadonlyStorageTextureInFragmentShader) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12, Vulkan and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsVulkan() || IsOpenGL());
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
|
||||
|
||||
// When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
|
||||
// read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
|
||||
|
@ -370,8 +372,8 @@ TEST_P(StorageTextureTests, ReadonlyStorageTextureInFragmentShader) {
|
|||
|
||||
// Test that write-only storage textures are supported in compute shader.
|
||||
TEST_P(StorageTextureTests, WriteonlyStorageTextureInComputeShader) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12, Vulkan and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsVulkan() || IsOpenGL());
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
|
||||
|
||||
// Prepare the write-only storage texture.
|
||||
// TODO(jiawei.shao@intel.com): test more texture formats.
|
||||
|
@ -400,8 +402,8 @@ TEST_P(StorageTextureTests, WriteonlyStorageTextureInComputeShader) {
|
|||
|
||||
// Test that write-only storage textures are supported in fragment shader.
|
||||
TEST_P(StorageTextureTests, WriteonlyStorageTextureInFragmentShader) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12, Vulkan and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsVulkan() || IsOpenGL());
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
|
||||
|
||||
// Prepare the write-only storage texture.
|
||||
// TODO(jiawei.shao@intel.com): test more texture formats.
|
||||
|
|
Loading…
Reference in New Issue