• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/graphite/dawn/DawnResourceProvider.h"
9 
10 #include "include/gpu/graphite/BackendTexture.h"
11 #include "src/gpu/graphite/ComputePipeline.h"
12 #include "src/gpu/graphite/dawn/DawnBuffer.h"
13 #include "src/gpu/graphite/dawn/DawnGraphicsPipeline.h"
14 #include "src/gpu/graphite/dawn/DawnSampler.h"
15 #include "src/gpu/graphite/dawn/DawnSharedContext.h"
16 #include "src/gpu/graphite/dawn/DawnTexture.h"
17 
18 namespace skgpu::graphite {
19 
20 namespace {
create_shader_module(const wgpu::Device & device,const char * source)21 wgpu::ShaderModule create_shader_module(const wgpu::Device& device, const char* source) {
22     wgpu::ShaderModuleWGSLDescriptor wgslDesc;
23     wgslDesc.source = source;
24     wgpu::ShaderModuleDescriptor descriptor;
25     descriptor.nextInChain = &wgslDesc;
26     return device.CreateShaderModule(&descriptor);
27 }
28 
create_blit_render_pipeline(const wgpu::Device & device,const char * label,wgpu::ShaderModule vsModule,wgpu::ShaderModule fsModule,wgpu::TextureFormat renderPassColorFormat,wgpu::TextureFormat renderPassDepthStencilFormat,int numSamples)29 wgpu::RenderPipeline create_blit_render_pipeline(const wgpu::Device& device,
30                                                  const char* label,
31                                                  wgpu::ShaderModule vsModule,
32                                                  wgpu::ShaderModule fsModule,
33                                                  wgpu::TextureFormat renderPassColorFormat,
34                                                  wgpu::TextureFormat renderPassDepthStencilFormat,
35                                                  int numSamples) {
36     wgpu::RenderPipelineDescriptor descriptor;
37 #if defined(SK_DEBUG)
38     descriptor.label = label;
39 #endif
40     descriptor.layout = nullptr;
41 
42     wgpu::ColorTargetState colorTarget;
43     colorTarget.format = renderPassColorFormat;
44     colorTarget.blend = nullptr;
45     colorTarget.writeMask = wgpu::ColorWriteMask::All;
46 
47     wgpu::DepthStencilState depthStencil;
48     if (renderPassDepthStencilFormat != wgpu::TextureFormat::Undefined) {
49         depthStencil.format = renderPassDepthStencilFormat;
50         depthStencil.depthWriteEnabled = false;
51         depthStencil.depthCompare = wgpu::CompareFunction::Always;
52 
53         descriptor.depthStencil = &depthStencil;
54     }
55 
56     wgpu::FragmentState fragment;
57     fragment.module = std::move(fsModule);
58     fragment.entryPoint = "main";
59     fragment.targetCount = 1;
60     fragment.targets = &colorTarget;
61     descriptor.fragment = &fragment;
62 
63     descriptor.vertex.module = std::move(vsModule);
64     descriptor.vertex.entryPoint = "main";
65     descriptor.vertex.constantCount = 0;
66     descriptor.vertex.constants = nullptr;
67     descriptor.vertex.bufferCount = 0;
68     descriptor.vertex.buffers = nullptr;
69 
70     descriptor.primitive.frontFace = wgpu::FrontFace::CCW;
71     descriptor.primitive.cullMode = wgpu::CullMode::None;
72     descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
73     descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Undefined;
74 
75     descriptor.multisample.count = numSamples;
76     descriptor.multisample.mask = 0xFFFFFFFF;
77     descriptor.multisample.alphaToCoverageEnabled = false;
78 
79     return device.CreateRenderPipeline(&descriptor);
80 }
81 }
82 
DawnResourceProvider(SharedContext * sharedContext,SingleOwner * singleOwner)83 DawnResourceProvider::DawnResourceProvider(SharedContext* sharedContext,
84                                            SingleOwner* singleOwner)
85         : ResourceProvider(sharedContext, singleOwner) {}
86 
87 DawnResourceProvider::~DawnResourceProvider() = default;
88 
findOrCreateBlitWithDrawPipeline(const RenderPassDesc & renderPassDesc)89 wgpu::RenderPipeline DawnResourceProvider::findOrCreateBlitWithDrawPipeline(
90         const RenderPassDesc& renderPassDesc) {
91     uint64_t renderPassKey =
92             this->dawnSharedContext()->dawnCaps()->getRenderPassDescKey(renderPassDesc);
93     wgpu::RenderPipeline pipeline = fBlitWithDrawPipelines[renderPassKey];
94     if (!pipeline) {
95         static constexpr char kVertexShaderText[] = R"(
96             var<private> fullscreenTriPositions : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
97                 vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
98 
99             @vertex
100             fn main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4<f32> {
101                 return vec4(fullscreenTriPositions[vertexIndex], 1.0, 1.0);
102             }
103         )";
104 
105         static constexpr char kFragmentShaderText[] = R"(
106             @group(0) @binding(0) var colorMap: texture_2d<f32>;
107 
108             @fragment
109             fn main(@builtin(position) fragPosition : vec4<f32>) -> @location(0) vec4<f32> {
110                 var coords : vec2<i32> = vec2<i32>(i32(fragPosition.x), i32(fragPosition.y));
111                 return textureLoad(colorMap, coords, 0);
112             }
113         )";
114 
115         auto vsModule = create_shader_module(dawnSharedContext()->device(), kVertexShaderText);
116         auto fsModule = create_shader_module(dawnSharedContext()->device(), kFragmentShaderText);
117 
118         pipeline = create_blit_render_pipeline(
119                 dawnSharedContext()->device(),
120                 /*label=*/"BlitWithDraw",
121                 std::move(vsModule),
122                 std::move(fsModule),
123                 /*renderPassColorFormat=*/
124                 renderPassDesc.fColorAttachment.fTextureInfo.dawnTextureSpec().fFormat,
125                 /*renderPassDepthStencilFormat=*/
126                 renderPassDesc.fDepthStencilAttachment.fTextureInfo.isValid()
127                         ? renderPassDesc.fDepthStencilAttachment.fTextureInfo.dawnTextureSpec()
128                                   .fFormat
129                         : wgpu::TextureFormat::Undefined,
130                 /*numSamples=*/renderPassDesc.fColorAttachment.fTextureInfo.numSamples());
131 
132         if (pipeline) {
133             fBlitWithDrawPipelines.set(renderPassKey, pipeline);
134         }
135     }
136 
137     return pipeline;
138 }
139 
createWrappedTexture(const BackendTexture & texture)140 sk_sp<Texture> DawnResourceProvider::createWrappedTexture(const BackendTexture& texture) {
141     wgpu::Texture dawnTexture         = texture.getDawnTexture();
142     wgpu::TextureView dawnTextureView = texture.getDawnTextureView();
143     SkASSERT(!dawnTexture || !dawnTextureView);
144 
145     if (!dawnTexture && !dawnTextureView) {
146         return {};
147     }
148 
149     if (dawnTexture) {
150         return DawnTexture::MakeWrapped(this->dawnSharedContext(),
151                                         texture.dimensions(),
152                                         texture.info(),
153                                         std::move(dawnTexture));
154     } else {
155         return DawnTexture::MakeWrapped(this->dawnSharedContext(),
156                                         texture.dimensions(),
157                                         texture.info(),
158                                         std::move(dawnTextureView));
159     }
160 }
161 
findOrCreateDiscardableMSAALoadTexture(SkISize dimensions,const TextureInfo & msaaInfo)162 sk_sp<DawnTexture> DawnResourceProvider::findOrCreateDiscardableMSAALoadTexture(
163         SkISize dimensions, const TextureInfo& msaaInfo) {
164     SkASSERT(msaaInfo.isValid());
165 
166     DawnTextureInfo dawnMsaaLoadTextureInfo;
167     msaaInfo.getDawnTextureInfo(&dawnMsaaLoadTextureInfo);
168     dawnMsaaLoadTextureInfo.fSampleCount = 1;
169     dawnMsaaLoadTextureInfo.fUsage |= wgpu::TextureUsage::TextureBinding;
170 
171     auto texture = this->findOrCreateDiscardableMSAAAttachment(dimensions, dawnMsaaLoadTextureInfo);
172 
173     return sk_sp<DawnTexture>(static_cast<DawnTexture*>(texture.release()));
174 }
175 
createGraphicsPipeline(const RuntimeEffectDictionary * runtimeDict,const GraphicsPipelineDesc & pipelineDesc,const RenderPassDesc & renderPassDesc)176 sk_sp<GraphicsPipeline> DawnResourceProvider::createGraphicsPipeline(
177         const RuntimeEffectDictionary* runtimeDict,
178         const GraphicsPipelineDesc& pipelineDesc,
179         const RenderPassDesc& renderPassDesc) {
180     return DawnGraphicsPipeline::Make(this->dawnSharedContext(),
181                                       this->skslCompiler(),
182                                       runtimeDict,
183                                       pipelineDesc,
184                                       renderPassDesc);
185 }
186 
createComputePipeline(const ComputePipelineDesc &)187 sk_sp<ComputePipeline> DawnResourceProvider::createComputePipeline(const ComputePipelineDesc&) {
188     SkASSERT(false);
189     return nullptr;
190 }
191 
createTexture(SkISize dimensions,const TextureInfo & info,skgpu::Budgeted budgeted)192 sk_sp<Texture> DawnResourceProvider::createTexture(SkISize dimensions,
193                                                    const TextureInfo& info,
194                                                    skgpu::Budgeted budgeted) {
195     return DawnTexture::Make(this->dawnSharedContext(), dimensions, info, budgeted);
196 }
197 
createBuffer(size_t size,BufferType type,PrioritizeGpuReads prioritizeGpuReads)198 sk_sp<Buffer> DawnResourceProvider::createBuffer(size_t size,
199                                                  BufferType type,
200                                                  PrioritizeGpuReads prioritizeGpuReads) {
201     return DawnBuffer::Make(this->dawnSharedContext(), size, type, prioritizeGpuReads);
202 }
203 
createSampler(const SkSamplingOptions & options,SkTileMode xTileMode,SkTileMode yTileMode)204 sk_sp<Sampler> DawnResourceProvider::createSampler(const SkSamplingOptions& options,
205                                                    SkTileMode xTileMode,
206                                                    SkTileMode yTileMode) {
207     return DawnSampler::Make(this->dawnSharedContext(), options, xTileMode, yTileMode);
208 }
209 
onCreateBackendTexture(SkISize dimensions,const TextureInfo & info)210 BackendTexture DawnResourceProvider::onCreateBackendTexture(SkISize dimensions,
211                                                             const TextureInfo& info) {
212     wgpu::Texture texture = DawnTexture::MakeDawnTexture(this->dawnSharedContext(),
213                                                          dimensions,
214                                                          info);
215     if (!texture) {
216         return {};
217     }
218 
219     return BackendTexture(std::move(texture));
220 }
221 
onDeleteBackendTexture(BackendTexture & texture)222 void DawnResourceProvider::onDeleteBackendTexture(BackendTexture& texture) {
223     SkASSERT(texture.isValid());
224     SkASSERT(texture.backend() == BackendApi::kDawn);
225 
226     // Nothing to be done here as all the the cleanup of Dawn's resources will be done inside
227     // BackendTexture::~BackendTexture().
228 }
229 
dawnSharedContext() const230 const DawnSharedContext* DawnResourceProvider::dawnSharedContext() const {
231     return static_cast<const DawnSharedContext*>(fSharedContext);
232 }
233 
234 } // namespace skgpu::graphite
235