Add basic supports of storage textures on OpenGL
This patch adds the basic supports of read-only and write-only storage textures on OpenGL backend. Currently on OpenGL backend we only support using either a layer of a texture or the entire texture as either read- only or write-only storage texture. BUG=dawn:267 TEST=dawn_end2end_tests Change-Id: I235b98d8d961a17739ea35eec9726dcc80889c4b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22180 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
da6dccd7c5
commit
0e5301c23e
|
@ -194,8 +194,6 @@ namespace dawn_native {
|
|||
case wgpu::BindingType::ComparisonSampler:
|
||||
DAWN_TRY(ValidateSamplerBinding(device, entry, bindingInfo.type));
|
||||
break;
|
||||
// TODO(jiawei.shao@intel.com): support creating bind group with read-only and
|
||||
// write-only storage textures.
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Storage,
|
||||
|
|
|
@ -14,11 +14,54 @@
|
|||
|
||||
#include "dawn_native/opengl/BindGroupGL.h"
|
||||
|
||||
#include "dawn_native/Texture.h"
|
||||
#include "dawn_native/opengl/BindGroupLayoutGL.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
MaybeError ValidateGLBindGroupDescriptor(const BindGroupDescriptor* descriptor) {
|
||||
const BindGroupLayoutBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
|
||||
for (uint32_t i = 0; i < descriptor->entryCount; ++i) {
|
||||
const BindGroupEntry& entry = descriptor->entries[i];
|
||||
|
||||
const auto& it = bindingMap.find(BindingNumber(entry.binding));
|
||||
BindingIndex bindingIndex = it->second;
|
||||
ASSERT(bindingIndex < descriptor->layout->GetBindingCount());
|
||||
|
||||
const BindingInfo& bindingInfo = descriptor->layout->GetBindingInfo(bindingIndex);
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
||||
ASSERT(entry.textureView != nullptr);
|
||||
const uint32_t textureViewLayerCount = entry.textureView->GetLayerCount();
|
||||
if (textureViewLayerCount != 1 &&
|
||||
textureViewLayerCount !=
|
||||
entry.textureView->GetTexture()->GetArrayLayers()) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Currently the OpenGL backend only supports either binding a layer or "
|
||||
"the entire texture as storage texture.");
|
||||
}
|
||||
} break;
|
||||
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BindGroup::BindGroup(Device* device, const BindGroupDescriptor* descriptor)
|
||||
: BindGroupBase(this, device, descriptor) {
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace dawn_native { namespace opengl {
|
|||
class BindGroupLayout;
|
||||
class Device;
|
||||
|
||||
MaybeError ValidateGLBindGroupDescriptor(const BindGroupDescriptor* descriptor);
|
||||
|
||||
class BindGroup final : public BindGroupBase, public PlacementAllocated {
|
||||
public:
|
||||
BindGroup(Device* device, const BindGroupDescriptor* descriptor);
|
||||
|
|
|
@ -312,9 +312,45 @@ namespace dawn_native { namespace opengl {
|
|||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
||||
TextureView* view =
|
||||
ToBackend(group->GetBindingAsTextureView(bindingIndex));
|
||||
Texture* texture = ToBackend(view->GetTexture());
|
||||
GLuint handle = texture->GetHandle();
|
||||
GLuint imageIndex = indices[bindingIndex];
|
||||
|
||||
GLenum access;
|
||||
switch (bindingInfo.type) {
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
access = GL_READ_ONLY;
|
||||
break;
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
access = GL_WRITE_ONLY;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
// OpenGL ES only supports either binding a layer or the entire texture
|
||||
// in glBindImageTexture().
|
||||
GLboolean isLayered;
|
||||
if (view->GetLayerCount() == 1) {
|
||||
isLayered = GL_FALSE;
|
||||
} else if (texture->GetArrayLayers() == view->GetLayerCount()) {
|
||||
isLayered = GL_TRUE;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
gl.BindImageTexture(imageIndex, handle, view->GetBaseMipLevel(),
|
||||
isLayered, view->GetBaseArrayLayer(), access,
|
||||
texture->GetGLFormat().internalFormat);
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) {
|
||||
DAWN_TRY(ValidateGLBindGroupDescriptor(descriptor));
|
||||
return BindGroup::Create(this, descriptor);
|
||||
}
|
||||
ResultOrError<BindGroupLayoutBase*> Device::CreateBindGroupLayoutImpl(
|
||||
|
|
|
@ -142,9 +142,16 @@ namespace dawn_native { namespace opengl {
|
|||
// emulation
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
||||
GLint location = gl.GetUniformLocation(mProgram, name.c_str());
|
||||
if (location != -1) {
|
||||
gl.Uniform1i(location, indices[group][bindingIndex]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace dawn_native { namespace opengl {
|
|||
GLuint samplerIndex = 0;
|
||||
GLuint sampledTextureIndex = 0;
|
||||
GLuint ssboIndex = 0;
|
||||
GLuint storageTextureIndex = 0;
|
||||
|
||||
for (uint32_t group : IterateBitSet(GetBindGroupLayoutsMask())) {
|
||||
const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
|
||||
|
@ -53,9 +54,13 @@ namespace dawn_native { namespace opengl {
|
|||
ssboIndex++;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
mIndexInfo[group][bindingIndex] = storageTextureIndex;
|
||||
storageTextureIndex++;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
|
|
|
@ -176,12 +176,26 @@ namespace dawn_native { namespace opengl {
|
|||
BindingNumber bindingNumber = it.first;
|
||||
const auto& info = it.second;
|
||||
|
||||
uint32_t resourceId;
|
||||
switch (info.type) {
|
||||
// When the resource is a uniform or shader storage block, we should change the
|
||||
// block name instead of the instance name.
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
resourceId = info.base_type_id;
|
||||
break;
|
||||
default:
|
||||
resourceId = info.id;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
|
||||
mSpvcContext.SetName(info.base_type_id, GetBindingName(group, bindingNumber));
|
||||
mSpvcContext.SetName(resourceId, GetBindingName(group, bindingNumber));
|
||||
mSpvcContext.UnsetDecoration(info.id, shaderc_spvc_decoration_binding);
|
||||
mSpvcContext.UnsetDecoration(info.id, shaderc_spvc_decoration_descriptorset);
|
||||
} else {
|
||||
compiler->set_name(info.base_type_id, GetBindingName(group, bindingNumber));
|
||||
compiler->set_name(resourceId, GetBindingName(group, bindingNumber));
|
||||
compiler->unset_decoration(info.id, spv::DecorationBinding);
|
||||
compiler->unset_decoration(info.id, spv::DecorationDescriptorSet);
|
||||
}
|
||||
|
|
|
@ -342,9 +342,6 @@ 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 OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -380,9 +377,6 @@ 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 OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -424,9 +418,6 @@ 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 OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -460,9 +451,6 @@ 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 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -482,9 +470,6 @@ 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 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -504,9 +489,6 @@ TEST_P(StorageTextureTests, WriteonlyStorageTextureInFragmentShader) {
|
|||
|
||||
// Verify 2D array read-only storage texture works correctly.
|
||||
TEST_P(StorageTextureTests, Readonly2DArrayStorageTexture) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -556,9 +538,6 @@ TEST_P(StorageTextureTests, Readonly2DArrayStorageTexture) {
|
|||
|
||||
// Verify 2D array write-only storage texture works correctly.
|
||||
TEST_P(StorageTextureTests, Writeonly2DArrayStorageTexture) {
|
||||
// TODO(jiawei.shao@intel.com): support write-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -633,9 +612,6 @@ class StorageTextureZeroInitTests : public StorageTextureTests {
|
|||
// Verify that the texture is correctly cleared to 0 before its first usage as a read-only storage
|
||||
// texture in a render pass.
|
||||
TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInRenderPass) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -668,9 +644,6 @@ TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInRenderPa
|
|||
// Verify that the texture is correctly cleared to 0 before its first usage as a read-only storage
|
||||
// texture in a compute pass.
|
||||
TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInComputePass) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -704,9 +677,6 @@ TEST_P(StorageTextureZeroInitTests, ReadonlyStorageTextureClearsToZeroInComputeP
|
|||
// Verify that the texture is correctly cleared to 0 before its first usage as a write-only storage
|
||||
// storage texture in a render pass.
|
||||
TEST_P(StorageTextureZeroInitTests, WriteonlyStorageTextureClearsToZeroInRenderPass) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
@ -726,9 +696,6 @@ TEST_P(StorageTextureZeroInitTests, WriteonlyStorageTextureClearsToZeroInRenderP
|
|||
// Verify that the texture is correctly cleared to 0 before its first usage as a write-only storage
|
||||
// texture in a compute pass.
|
||||
TEST_P(StorageTextureZeroInitTests, WriteonlyStorageTextureClearsToZeroInComputePass) {
|
||||
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
|
||||
DAWN_SKIP_TEST_IF(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.
|
||||
// TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
|
||||
|
|
Loading…
Reference in New Issue