28constexpr int kBufferBindingSizeAlignment = 16;
29constexpr int kMaxNumberOfCachedBufferBindGroups = 32;
30constexpr int kMaxNumberOfCachedTextureBindGroups = 4096;
32wgpu::ShaderModule create_shader_module(
const wgpu::Device&
device,
const char*
source) {
33 wgpu::ShaderModuleWGSLDescriptor wgslDesc;
35 wgpu::ShaderModuleDescriptor descriptor;
36 descriptor.nextInChain = &wgslDesc;
37 return device.CreateShaderModule(&descriptor);
40wgpu::RenderPipeline create_blit_render_pipeline(
const DawnSharedContext* sharedContext,
42 wgpu::ShaderModule vsModule,
43 wgpu::ShaderModule fsModule,
44 wgpu::TextureFormat renderPassColorFormat,
45 wgpu::TextureFormat renderPassDepthStencilFormat,
47 wgpu::RenderPipelineDescriptor descriptor;
48 descriptor.label = label;
49 descriptor.layout =
nullptr;
51 wgpu::ColorTargetState colorTarget;
52 colorTarget.format = renderPassColorFormat;
53 colorTarget.blend =
nullptr;
54 colorTarget.writeMask = wgpu::ColorWriteMask::All;
56 wgpu::DepthStencilState depthStencil;
57 if (renderPassDepthStencilFormat != wgpu::TextureFormat::Undefined) {
58 depthStencil.format = renderPassDepthStencilFormat;
59 depthStencil.depthWriteEnabled =
false;
60 depthStencil.depthCompare = wgpu::CompareFunction::Always;
62 descriptor.depthStencil = &depthStencil;
65 wgpu::FragmentState fragment;
66 fragment.module = std::move(fsModule);
67 fragment.entryPoint =
"main";
68 fragment.targetCount = 1;
69 fragment.targets = &colorTarget;
70 descriptor.fragment = &fragment;
72 descriptor.vertex.module = std::move(vsModule);
73 descriptor.vertex.entryPoint =
"main";
74 descriptor.vertex.constantCount = 0;
75 descriptor.vertex.constants =
nullptr;
76 descriptor.vertex.bufferCount = 0;
77 descriptor.vertex.buffers =
nullptr;
79 descriptor.primitive.frontFace = wgpu::FrontFace::CCW;
80 descriptor.primitive.cullMode = wgpu::CullMode::None;
81 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
82 descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Undefined;
84 descriptor.multisample.count = numSamples;
85 descriptor.multisample.mask = 0xFFFFFFFF;
86 descriptor.multisample.alphaToCoverageEnabled =
false;
88 std::optional<DawnErrorChecker> errorChecker;
89 if (sharedContext->dawnCaps()->allowScopedErrorChecks()) {
90 errorChecker.emplace(sharedContext);
92 auto pipeline = sharedContext->device().CreateRenderPipeline(&descriptor);
100UniqueKey make_ubo_bind_group_key(
101 const std::array<std::pair<const DawnBuffer*, uint32_t>, 4>& boundBuffersAndSizes) {
112 &uniqueKey, kBufferBindGroupDomain, 8,
"GraphicsPipelineBufferBindGroup");
114 for (uint32_t
i = 0;
i < boundBuffersAndSizes.size(); ++
i) {
115 const DawnBuffer* boundBuffer = boundBuffersAndSizes[
i].first;
116 const uint32_t bindingSize = boundBuffersAndSizes[
i].second;
118 builder[2 *
i] = boundBuffer->uniqueID().asUInt();
132UniqueKey make_texture_bind_group_key(
const DawnSampler* sampler,
const DawnTexture*
texture) {
138 kTextureBindGroupDomain,
140 "GraphicsPipelineSingleTextureSamplerBindGroup");
142 builder[0] = sampler->uniqueID().asUInt();
155 size_t resourceBudget)
157 , fUniformBufferBindGroupCache(kMaxNumberOfCachedBufferBindGroups)
158 , fSingleTextureSamplerBindGroups(kMaxNumberOfCachedTextureBindGroups) {}
164 uint64_t renderPassKey =
166 wgpu::RenderPipeline pipeline = fBlitWithDrawPipelines[renderPassKey];
168 static constexpr char kVertexShaderText[] = R
"(
169 var<private> fullscreenTriPositions : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
170 vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
173 fn main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4<f32> {
174 return vec4(fullscreenTriPositions[vertexIndex], 1.0, 1.0);
178 static constexpr char kFragmentShaderText[] = R
"(
179 @group(0) @binding(0) var colorMap: texture_2d<f32>;
182 fn main(@builtin(position) fragPosition : vec4<f32>) -> @location(0) vec4<f32> {
183 var coords : vec2<i32> = vec2<i32>(i32(fragPosition.x), i32(fragPosition.y));
184 return textureLoad(colorMap, coords, 0);
188 auto vsModule = create_shader_module(dawnSharedContext()->
device(), kVertexShaderText);
189 auto fsModule = create_shader_module(dawnSharedContext()->
device(), kFragmentShaderText);
191 pipeline = create_blit_render_pipeline(
202 : wgpu::TextureFormat::Undefined,
206 fBlitWithDrawPipelines.
set(renderPassKey, pipeline);
215 wgpu::Texture dawnTexture =
texture.getDawnTexturePtr();
216 wgpu::TextureView dawnTextureView =
texture.getDawnTextureViewPtr();
217 SkASSERT(!dawnTexture || !dawnTextureView);
219 if (!dawnTexture && !dawnTextureView) {
227 std::move(dawnTexture));
232 std::move(dawnTextureView));
242 msaaInfo.getDawnTextureInfo(&dawnMsaaLoadTextureInfo);
244 dawnMsaaLoadTextureInfo.
fUsage |= wgpu::TextureUsage::TextureBinding;
246#if !defined(__EMSCRIPTEN__)
253 dawnMsaaLoadTextureInfo.
fUsage &= (
~wgpu::TextureUsage::TransientAttachment);
273 const ComputePipelineDesc&
desc) {
278 const TextureInfo&
info,
292sk_sp<Sampler> DawnResourceProvider::createSampler(
const SamplerDesc& samplerDesc) {
294 samplerDesc.samplingOptions(),
295 samplerDesc.tileModeX(),
296 samplerDesc.tileModeY());
299BackendTexture DawnResourceProvider::onCreateBackendTexture(
SkISize dimensions,
300 const TextureInfo&
info) {
308 return BackendTexture(
texture.MoveToCHandle());
311void DawnResourceProvider::onDeleteBackendTexture(
const BackendTexture&
texture) {
317 wgpu::TextureView::Acquire(
texture.getDawnTextureViewPtr());
325 wgpu::Texture::Acquire(
texture.getDawnTexturePtr()).Destroy();
328DawnSharedContext* DawnResourceProvider::dawnSharedContext()
const {
335 std::string_view label) {
342 if (fUniformBuffersBindGroupLayout) {
343 return fUniformBuffersBindGroupLayout;
346 std::array<wgpu::BindGroupLayoutEntry, 4> entries;
350 entries[0].buffer.hasDynamicOffset =
true;
351 entries[0].buffer.minBindingSize = 0;
356 ? wgpu::BufferBindingType::ReadOnlyStorage
358 entries[1].buffer.hasDynamicOffset =
true;
359 entries[1].buffer.minBindingSize = 0;
362 entries[2].visibility = wgpu::ShaderStage::Fragment;
364 ? wgpu::BufferBindingType::ReadOnlyStorage
366 entries[2].buffer.hasDynamicOffset =
true;
367 entries[2].buffer.minBindingSize = 0;
373 entries[3].visibility = wgpu::ShaderStage::Fragment;
375 ? wgpu::BufferBindingType::ReadOnlyStorage
377 entries[3].buffer.hasDynamicOffset =
true;
378 entries[3].buffer.minBindingSize = 0;
380 wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
382 groupLayoutDesc.label =
"Uniform buffers bind group layout";
385 groupLayoutDesc.entryCount = entries.size();
386 groupLayoutDesc.entries = entries.data();
387 fUniformBuffersBindGroupLayout =
388 this->dawnSharedContext()->
device().CreateBindGroupLayout(&groupLayoutDesc);
390 return fUniformBuffersBindGroupLayout;
393const wgpu::BindGroupLayout&
395 if (fSingleTextureSamplerBindGroupLayout) {
396 return fSingleTextureSamplerBindGroupLayout;
399 std::array<wgpu::BindGroupLayoutEntry, 2> entries;
401 entries[0].binding = 0;
402 entries[0].visibility = wgpu::ShaderStage::Fragment;
403 entries[0].sampler.type = wgpu::SamplerBindingType::Filtering;
405 entries[1].binding = 1;
406 entries[1].visibility = wgpu::ShaderStage::Fragment;
407 entries[1].texture.sampleType = wgpu::TextureSampleType::Float;
408 entries[1].texture.viewDimension = wgpu::TextureViewDimension::e2D;
409 entries[1].texture.multisampled =
false;
411 wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
413 groupLayoutDesc.label =
"Single texture + sampler bind group layout";
416 groupLayoutDesc.entryCount = entries.size();
417 groupLayoutDesc.entries = entries.data();
418 fSingleTextureSamplerBindGroupLayout =
419 this->dawnSharedContext()->
device().CreateBindGroupLayout(&groupLayoutDesc);
421 return fSingleTextureSamplerBindGroupLayout;
424const wgpu::Buffer& DawnResourceProvider::getOrCreateNullBuffer() {
426 wgpu::BufferDescriptor
desc;
428 desc.label =
"UnusedBufferSlot";
431 wgpu::BufferUsage::Storage;
432 desc.size = kBufferBindingSizeAlignment;
433 desc.mappedAtCreation =
false;
435 fNullBuffer = this->dawnSharedContext()->
device().CreateBuffer(&
desc);
443 if (!fIntrinsicConstantBuffer) {
447 "IntrinsicConstantBuffer");
451 return fIntrinsicConstantBuffer;
455 const std::array<std::pair<const DawnBuffer*, uint32_t>, 4>& boundBuffersAndSizes) {
456 auto key = make_ubo_bind_group_key(boundBuffersAndSizes);
457 auto* existingBindGroup = fUniformBufferBindGroupCache.
find(
key);
458 if (existingBindGroup) {
460 return *existingBindGroup;
464 std::array<wgpu::BindGroupEntry, 4> entries;
466 constexpr uint32_t kBindingIndices[] = {
473 for (uint32_t
i = 0;
i < boundBuffersAndSizes.size(); ++
i) {
474 const DawnBuffer* boundBuffer = boundBuffersAndSizes[
i].first;
475 const uint32_t bindingSize = boundBuffersAndSizes[
i].second;
477 entries[
i].binding = kBindingIndices[
i];
478 entries[
i].offset = 0;
481 entries[
i].size =
SkAlignTo(bindingSize, kBufferBindingSizeAlignment);
483 entries[
i].buffer = this->getOrCreateNullBuffer();
484 entries[
i].size = wgpu::kWholeSize;
488 wgpu::BindGroupDescriptor
desc;
490 desc.entryCount = entries.size();
491 desc.entries = entries.data();
493 const auto&
device = this->dawnSharedContext()->
device();
494 auto bindGroup =
device.CreateBindGroup(&
desc);
496 return *fUniformBufferBindGroupCache.
insert(
key, bindGroup);
501 auto key = make_texture_bind_group_key(sampler,
texture);
502 auto* existingBindGroup = fSingleTextureSamplerBindGroups.
find(
key);
503 if (existingBindGroup) {
505 return *existingBindGroup;
508 std::array<wgpu::BindGroupEntry, 2> entries;
510 entries[0].binding = 0;
512 entries[1].binding = 1;
513 entries[1].textureView =
texture->sampleTextureView();
515 wgpu::BindGroupDescriptor
desc;
517 desc.entryCount = entries.size();
518 desc.entries = entries.data();
520 const auto&
device = this->dawnSharedContext()->
device();
521 auto bindGroup =
device.CreateBindGroup(&
desc);
523 return *fSingleTextureSamplerBindGroups.
insert(
key, bindGroup);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
GrTriangulator::Vertex Vertex
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
SkMeshSpecification::Uniform Uniform
V * insert(const K &key, V value)
static Domain GenerateDomain()
bool setBackendLabels() const
bool storageBufferPreferred() const
static sk_sp< DawnBuffer > Make(const DawnSharedContext *, size_t size, BufferType type, AccessPattern)
const wgpu::Buffer & dawnBuffer() const
uint64_t getRenderPassDescKeyForPipeline(const RenderPassDesc &renderPassDesc) const
static sk_sp< DawnComputePipeline > Make(const DawnSharedContext *, const ComputePipelineDesc &)
static constexpr unsigned int kRenderStepUniformBufferIndex
static constexpr unsigned int kPaintUniformBufferIndex
static constexpr unsigned int kGradientBufferIndex
static sk_sp< DawnGraphicsPipeline > Make(const DawnSharedContext *sharedContext, DawnResourceProvider *resourceProvider, const RuntimeEffectDictionary *runtimeDict, const GraphicsPipelineDesc &pipelineDesc, const RenderPassDesc &renderPassDesc)
static constexpr unsigned int kIntrinsicUniformBufferIndex
~DawnResourceProvider() override
const wgpu::BindGroup & findOrCreateSingleTextureSamplerBindGroup(const DawnSampler *sampler, const DawnTexture *texture)
DawnResourceProvider(SharedContext *sharedContext, SingleOwner *, uint32_t recorderID, size_t resourceBudget)
const wgpu::BindGroupLayout & getOrCreateSingleTextureSamplerBindGroupLayout()
sk_sp< DawnTexture > findOrCreateDiscardableMSAALoadTexture(SkISize dimensions, const TextureInfo &msaaInfo)
const sk_sp< DawnBuffer > & getOrCreateIntrinsicConstantBuffer()
const wgpu::BindGroupLayout & getOrCreateUniformBuffersBindGroupLayout()
const wgpu::BindGroup & findOrCreateUniformBuffersBindGroup(const std::array< std::pair< const DawnBuffer *, uint32_t >, 4 > &boundBuffersAndSizes)
wgpu::RenderPipeline findOrCreateBlitWithDrawPipeline(const RenderPassDesc &renderPassDesc)
sk_sp< DawnBuffer > findOrCreateDawnBuffer(size_t size, BufferType type, AccessPattern, std::string_view label)
const wgpu::Sampler & dawnSampler() const
static sk_sp< DawnSampler > Make(const DawnSharedContext *, const SkSamplingOptions &samplingOptions, SkTileMode xTileMode, SkTileMode yTileMode)
const DawnCaps * dawnCaps() const
const wgpu::Device & device() const
static sk_sp< Texture > MakeWrapped(const DawnSharedContext *, SkISize dimensions, const TextureInfo &, wgpu::Texture)
static wgpu::Texture MakeDawnTexture(const DawnSharedContext *, SkISize dimensions, const TextureInfo &)
static sk_sp< Texture > Make(const DawnSharedContext *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
sk_sp< Texture > findOrCreateDiscardableMSAAAttachment(SkISize dimensions, const TextureInfo &)
sk_sp< Buffer > findOrCreateBuffer(size_t size, BufferType type, AccessPattern, std::string_view label)
SharedContext * fSharedContext
const Caps * caps() const
uint32_t numSamples() const
DlVertices::Builder Builder
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
wgpu::TextureUsage fUsage
AttachmentDesc fDepthStencilAttachment
AttachmentDesc fColorAttachment