[graphite] Move Dawn BindGroupLayouts from ResourceProvider to SharedContext
This reduces race conditions wrt the ResourceProvider's lifetime. I've tried to make this CL as mechanical as possible.
Bug: b/434712686
Change-Id: Ifa7c860f464d710999cf109bed9526d792b9149c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1056196
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Thomas Smith <thomsmit@google.com>
diff --git a/src/gpu/graphite/dawn/DawnGraphicsPipeline.cpp b/src/gpu/graphite/dawn/DawnGraphicsPipeline.cpp
index 4a4f856..2646bfb 100644
--- a/src/gpu/graphite/dawn/DawnGraphicsPipeline.cpp
+++ b/src/gpu/graphite/dawn/DawnGraphicsPipeline.cpp
@@ -492,7 +492,7 @@
skia_private::TArray<sk_sp<DawnSampler>> immutableSamplers;
{
SkASSERT(resourceProvider);
- groupLayouts[0] = resourceProvider->getOrCreateUniformBuffersBindGroupLayout();
+ groupLayouts[0] = sharedContext->getUniformBuffersBindGroupLayout();
if (!groupLayouts[0]) {
return {};
}
@@ -502,8 +502,7 @@
// Check if we can optimize for the common case of a single texture + 1 dynamic sampler
if (numTexturesAndSamplers == 2 &&
!(samplerDescArrPtr && samplerDescArrPtr->at(0).isImmutable())) {
- groupLayouts[1] =
- resourceProvider->getOrCreateSingleTextureSamplerBindGroupLayout();
+ groupLayouts[1] = sharedContext->getSingleTextureSamplerBindGroupLayout();
} else {
std::vector<wgpu::BindGroupLayoutEntry> entries(numTexturesAndSamplers);
#if !defined(__EMSCRIPTEN__)
diff --git a/src/gpu/graphite/dawn/DawnResourceProvider.cpp b/src/gpu/graphite/dawn/DawnResourceProvider.cpp
index 5efcaaa..ed6ef53 100644
--- a/src/gpu/graphite/dawn/DawnResourceProvider.cpp
+++ b/src/gpu/graphite/dawn/DawnResourceProvider.cpp
@@ -636,93 +636,6 @@
return sk_sp<DawnBuffer>(ptr);
}
-const wgpu::BindGroupLayout& DawnResourceProvider::getOrCreateUniformBuffersBindGroupLayout() {
- SKGPU_ASSERT_SINGLE_OWNER(fSingleOwner)
-
- if (fUniformBuffersBindGroupLayout) {
- return fUniformBuffersBindGroupLayout;
- }
-
- std::array<wgpu::BindGroupLayoutEntry, 4> entries;
- entries[0].binding = DawnGraphicsPipeline::kIntrinsicUniformBufferIndex;
- entries[0].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
- entries[0].buffer.type = wgpu::BufferBindingType::Uniform;
- entries[0].buffer.hasDynamicOffset = true;
- entries[0].buffer.minBindingSize = 0;
-
- entries[1].binding = DawnGraphicsPipeline::kRenderStepUniformBufferIndex;
- entries[1].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
- entries[1].buffer.type = fSharedContext->caps()->storageBufferSupport()
- ? wgpu::BufferBindingType::ReadOnlyStorage
- : wgpu::BufferBindingType::Uniform;
- entries[1].buffer.hasDynamicOffset = true;
- entries[1].buffer.minBindingSize = 0;
-
- entries[2].binding = DawnGraphicsPipeline::kPaintUniformBufferIndex;
- entries[2].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
- entries[2].buffer.type = fSharedContext->caps()->storageBufferSupport()
- ? wgpu::BufferBindingType::ReadOnlyStorage
- : wgpu::BufferBindingType::Uniform;
- entries[2].buffer.hasDynamicOffset = true;
- entries[2].buffer.minBindingSize = 0;
-
- // Gradient buffer will only be used when storage buffers are preferred, else large
- // gradients use a texture fallback, set binding type as a uniform when not in use to
- // satisfy any binding type restricions for non-supported ssbo devices.
- entries[3].binding = DawnGraphicsPipeline::kGradientBufferIndex;
- entries[3].visibility = wgpu::ShaderStage::Fragment;
- entries[3].buffer.type = fSharedContext->caps()->storageBufferSupport()
- ? wgpu::BufferBindingType::ReadOnlyStorage
- : wgpu::BufferBindingType::Uniform;
- entries[3].buffer.hasDynamicOffset = true;
- entries[3].buffer.minBindingSize = 0;
-
- wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
- if (fSharedContext->caps()->setBackendLabels()) {
- groupLayoutDesc.label = "Uniform buffers bind group layout";
- }
-
- groupLayoutDesc.entryCount = entries.size();
- groupLayoutDesc.entries = entries.data();
- fUniformBuffersBindGroupLayout =
- this->dawnSharedContext()->device().CreateBindGroupLayout(&groupLayoutDesc);
-
- return fUniformBuffersBindGroupLayout;
-}
-
-const wgpu::BindGroupLayout&
-DawnResourceProvider::getOrCreateSingleTextureSamplerBindGroupLayout() {
- SKGPU_ASSERT_SINGLE_OWNER(fSingleOwner)
-
- if (fSingleTextureSamplerBindGroupLayout) {
- return fSingleTextureSamplerBindGroupLayout;
- }
-
- std::array<wgpu::BindGroupLayoutEntry, 2> entries;
-
- entries[0].binding = 0;
- entries[0].visibility = wgpu::ShaderStage::Fragment;
- entries[0].sampler.type = wgpu::SamplerBindingType::Filtering;
-
- entries[1].binding = 1;
- entries[1].visibility = wgpu::ShaderStage::Fragment;
- entries[1].texture.sampleType = wgpu::TextureSampleType::Float;
- entries[1].texture.viewDimension = wgpu::TextureViewDimension::e2D;
- entries[1].texture.multisampled = false;
-
- wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
- if (fSharedContext->caps()->setBackendLabels()) {
- groupLayoutDesc.label = "Single texture + sampler bind group layout";
- }
-
- groupLayoutDesc.entryCount = entries.size();
- groupLayoutDesc.entries = entries.data();
- fSingleTextureSamplerBindGroupLayout =
- this->dawnSharedContext()->device().CreateBindGroupLayout(&groupLayoutDesc);
-
- return fSingleTextureSamplerBindGroupLayout;
-}
-
const wgpu::Buffer& DawnResourceProvider::getOrCreateNullBuffer() {
if (!fNullBuffer) {
wgpu::BufferDescriptor desc;
@@ -779,7 +692,7 @@
}
wgpu::BindGroupDescriptor desc;
- desc.layout = this->getOrCreateUniformBuffersBindGroupLayout();
+ desc.layout = this->dawnSharedContext()->getUniformBuffersBindGroupLayout();
desc.entryCount = entries.size();
desc.entries = entries.data();
@@ -808,7 +721,7 @@
entries[1].textureView = texture->sampleTextureView();
wgpu::BindGroupDescriptor desc;
- desc.layout = getOrCreateSingleTextureSamplerBindGroupLayout();
+ desc.layout = this->dawnSharedContext()->getSingleTextureSamplerBindGroupLayout();
desc.entryCount = entries.size();
desc.entries = entries.data();
diff --git a/src/gpu/graphite/dawn/DawnResourceProvider.h b/src/gpu/graphite/dawn/DawnResourceProvider.h
index 448a6c2..ce95d21 100644
--- a/src/gpu/graphite/dawn/DawnResourceProvider.h
+++ b/src/gpu/graphite/dawn/DawnResourceProvider.h
@@ -65,9 +65,6 @@
AccessPattern,
std::string_view label);
- const wgpu::BindGroupLayout& getOrCreateUniformBuffersBindGroupLayout();
- const wgpu::BindGroupLayout& getOrCreateSingleTextureSamplerBindGroupLayout();
-
// Find the cached bind group or create a new one based on the bound buffers and their
// binding sizes (boundBuffersAndSizes) for these uniforms (in order):
// - Intrinsic constants.
@@ -113,9 +110,6 @@
skia_private::THashMap<uint32_t, wgpu::RenderPipeline> fBlitWithDrawPipelines;
- wgpu::BindGroupLayout fUniformBuffersBindGroupLayout;
- wgpu::BindGroupLayout fSingleTextureSamplerBindGroupLayout;
-
wgpu::Buffer fNullBuffer;
template <size_t NumEntries>
diff --git a/src/gpu/graphite/dawn/DawnSharedContext.cpp b/src/gpu/graphite/dawn/DawnSharedContext.cpp
index 5525b4a..173a66e 100644
--- a/src/gpu/graphite/dawn/DawnSharedContext.cpp
+++ b/src/gpu/graphite/dawn/DawnSharedContext.cpp
@@ -11,6 +11,7 @@
#include "include/gpu/graphite/ContextOptions.h"
#include "include/gpu/graphite/dawn/DawnBackendContext.h"
#include "src/gpu/graphite/Log.h"
+#include "src/gpu/graphite/dawn/DawnGraphicsPipeline.h"
#include "src/gpu/graphite/dawn/DawnResourceProvider.h"
#include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE
@@ -69,7 +70,10 @@
, fDevice(backendContext.fDevice)
, fQueue(backendContext.fQueue)
, fTick(backendContext.fTick)
- , fNoopFragment(std::move(noopFragment)) {}
+ , fNoopFragment(std::move(noopFragment)) {
+ this->createUniformBuffersBindGroupLayout();
+ this->createSingleTextureSamplerBindGroupLayout();
+}
DawnSharedContext::~DawnSharedContext() {
// need to clear out resources before any allocator is removed
@@ -93,4 +97,76 @@
context->checkAsyncWorkCompletion();
};
+void DawnSharedContext::createUniformBuffersBindGroupLayout() {
+ const Caps* caps = this->caps();
+
+ std::array<wgpu::BindGroupLayoutEntry, 4> entries;
+ entries[0].binding = DawnGraphicsPipeline::kIntrinsicUniformBufferIndex;
+ entries[0].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
+ entries[0].buffer.type = wgpu::BufferBindingType::Uniform;
+ entries[0].buffer.hasDynamicOffset = true;
+ entries[0].buffer.minBindingSize = 0;
+
+ entries[1].binding = DawnGraphicsPipeline::kRenderStepUniformBufferIndex;
+ entries[1].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
+ entries[1].buffer.type = caps->storageBufferSupport()
+ ? wgpu::BufferBindingType::ReadOnlyStorage
+ : wgpu::BufferBindingType::Uniform;
+ entries[1].buffer.hasDynamicOffset = true;
+ entries[1].buffer.minBindingSize = 0;
+
+ entries[2].binding = DawnGraphicsPipeline::kPaintUniformBufferIndex;
+ entries[2].visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
+ entries[2].buffer.type = caps->storageBufferSupport()
+ ? wgpu::BufferBindingType::ReadOnlyStorage
+ : wgpu::BufferBindingType::Uniform;
+ entries[2].buffer.hasDynamicOffset = true;
+ entries[2].buffer.minBindingSize = 0;
+
+ // Gradient buffer will only be used when storage buffers are preferred, else large
+ // gradients use a texture fallback, set binding type as a uniform when not in use to
+ // satisfy any binding type restrictions for non-supported ssbo devices.
+ entries[3].binding = DawnGraphicsPipeline::kGradientBufferIndex;
+ entries[3].visibility = wgpu::ShaderStage::Fragment;
+ entries[3].buffer.type = caps->storageBufferSupport()
+ ? wgpu::BufferBindingType::ReadOnlyStorage
+ : wgpu::BufferBindingType::Uniform;
+ entries[3].buffer.hasDynamicOffset = true;
+ entries[3].buffer.minBindingSize = 0;
+
+ wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
+ if (caps->setBackendLabels()) {
+ groupLayoutDesc.label = "Uniform buffers bind group layout";
+ }
+
+ groupLayoutDesc.entryCount = entries.size();
+ groupLayoutDesc.entries = entries.data();
+ fUniformBuffersBindGroupLayout = this->device().CreateBindGroupLayout(&groupLayoutDesc);
+}
+
+void DawnSharedContext::createSingleTextureSamplerBindGroupLayout() {
+ const Caps* caps = this->caps();
+
+ std::array<wgpu::BindGroupLayoutEntry, 2> entries;
+
+ entries[0].binding = 0;
+ entries[0].visibility = wgpu::ShaderStage::Fragment;
+ entries[0].sampler.type = wgpu::SamplerBindingType::Filtering;
+
+ entries[1].binding = 1;
+ entries[1].visibility = wgpu::ShaderStage::Fragment;
+ entries[1].texture.sampleType = wgpu::TextureSampleType::Float;
+ entries[1].texture.viewDimension = wgpu::TextureViewDimension::e2D;
+ entries[1].texture.multisampled = false;
+
+ wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
+ if (caps->setBackendLabels()) {
+ groupLayoutDesc.label = "Single texture + sampler bind group layout";
+ }
+
+ groupLayoutDesc.entryCount = entries.size();
+ groupLayoutDesc.entries = entries.data();
+ fSingleTextureSamplerBindGroupLayout = this->device().CreateBindGroupLayout(&groupLayoutDesc);
+}
+
} // namespace skgpu::graphite
diff --git a/src/gpu/graphite/dawn/DawnSharedContext.h b/src/gpu/graphite/dawn/DawnSharedContext.h
index b45f66a..a94bfe2 100644
--- a/src/gpu/graphite/dawn/DawnSharedContext.h
+++ b/src/gpu/graphite/dawn/DawnSharedContext.h
@@ -43,6 +43,13 @@
void deviceTick(Context*) override;
+ const wgpu::BindGroupLayout& getUniformBuffersBindGroupLayout() const {
+ return fUniformBuffersBindGroupLayout;
+ }
+ const wgpu::BindGroupLayout& getSingleTextureSamplerBindGroupLayout() const {
+ return fSingleTextureSamplerBindGroupLayout;
+ }
+
private:
DawnSharedContext(const DawnBackendContext&,
std::unique_ptr<const DawnCaps>,
@@ -50,6 +57,9 @@
SkExecutor*,
SkSpan<sk_sp<SkRuntimeEffect>> userDefinedKnownRuntimeEffects);
+ void createUniformBuffersBindGroupLayout();
+ void createSingleTextureSamplerBindGroupLayout();
+
wgpu::Instance fInstance;
wgpu::Device fDevice;
wgpu::Queue fQueue;
@@ -57,6 +67,9 @@
// A noop fragment shader, it is used to workaround dawn a validation error(dawn doesn't allow
// a pipeline with a color attachment but without a fragment shader).
wgpu::ShaderModule fNoopFragment;
+
+ wgpu::BindGroupLayout fUniformBuffersBindGroupLayout;
+ wgpu::BindGroupLayout fSingleTextureSamplerBindGroupLayout;
};
} // namespace skgpu::graphite