• 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/PublicPrecompile.h"
9 
10 #include "include/core/SkColorSpace.h"
11 #include "include/core/SkColorType.h"
12 #include "include/gpu/graphite/precompile/Precompile.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/ContextPriv.h"
15 #include "src/gpu/graphite/ContextUtils.h"
16 #include "src/gpu/graphite/GraphicsPipeline.h"
17 #include "src/gpu/graphite/GraphicsPipelineDesc.h"
18 #include "src/gpu/graphite/KeyContext.h"
19 #include "src/gpu/graphite/Log.h"
20 #include "src/gpu/graphite/PrecompileInternal.h"
21 #include "src/gpu/graphite/RenderPassDesc.h"
22 #include "src/gpu/graphite/Renderer.h"
23 #include "src/gpu/graphite/RendererProvider.h"
24 #include "src/gpu/graphite/ResourceProvider.h"
25 #include "src/gpu/graphite/RuntimeEffectDictionary.h"
26 #include "src/gpu/graphite/UniquePaintParamsID.h"
27 #include "src/gpu/graphite/precompile/PaintOptionsPriv.h"
28 
29 namespace {
30 
31 using namespace skgpu::graphite;
32 
compile(const RendererProvider * rendererProvider,ResourceProvider * resourceProvider,const KeyContext & keyContext,UniquePaintParamsID uniqueID,DrawTypeFlags drawTypes,SkSpan<const RenderPassDesc> renderPassDescs,bool withPrimitiveBlender,Coverage coverage)33 void compile(const RendererProvider* rendererProvider,
34              ResourceProvider* resourceProvider,
35              const KeyContext& keyContext,
36              UniquePaintParamsID uniqueID,
37              DrawTypeFlags drawTypes,
38              SkSpan<const RenderPassDesc> renderPassDescs,
39              bool withPrimitiveBlender,
40              Coverage coverage) {
41     for (const Renderer* r : rendererProvider->renderers()) {
42         if (!(r->drawTypes() & drawTypes)) {
43             continue;
44         }
45 
46         if (r->emitsPrimitiveColor() != withPrimitiveBlender) {
47             // UniqueIDs are explicitly built either w/ or w/o primitiveBlending so must
48             // match what the Renderer requires
49             continue;
50         }
51 
52         if (r->coverage() != coverage) {
53             // For now, UniqueIDs are explicitly built with a specific type of coverage so must
54             // match what the Renderer requires
55             continue;
56         }
57 
58         for (auto&& s : r->steps()) {
59             SkASSERT(!s->performsShading() || s->emitsPrimitiveColor() == withPrimitiveBlender);
60 
61             UniquePaintParamsID paintID = s->performsShading() ? uniqueID
62                                                                : UniquePaintParamsID::InvalidID();
63             GraphicsPipelineDesc pipelineDesc(s, paintID);
64 
65             for (const RenderPassDesc& renderPassDesc : renderPassDescs) {
66                 sk_sp<GraphicsPipeline> pipeline = resourceProvider->findOrCreateGraphicsPipeline(
67                         keyContext.rtEffectDict(),
68                         pipelineDesc,
69                         renderPassDesc);
70                 if (!pipeline) {
71                     SKGPU_LOG_W("Failed to create GraphicsPipeline in precompile!");
72                     return;
73                 }
74             }
75         }
76     }
77 }
78 
79 } // anonymous namespace
80 
81 namespace skgpu::graphite {
82 
Precompile(Context * context,RuntimeEffectDictionary * rteDict,const GraphicsPipelineDesc & pipelineDesc,const RenderPassDesc & renderPassDesc)83 bool Precompile(Context* context,
84                 RuntimeEffectDictionary* rteDict,
85                 const GraphicsPipelineDesc& pipelineDesc,
86                 const RenderPassDesc& renderPassDesc) {
87     ResourceProvider* resourceProvider = context->priv().resourceProvider();
88 
89     sk_sp<GraphicsPipeline> pipeline = resourceProvider->findOrCreateGraphicsPipeline(
90             rteDict,
91             pipelineDesc,
92             renderPassDesc);
93     if (!pipeline) {
94         SKGPU_LOG_W("Failed to create GraphicsPipeline in precompile!");
95         return false;
96     }
97 
98     return true;
99 }
100 
Precompile(Context * context,const PaintOptions & options,DrawTypeFlags drawTypes)101 void Precompile(Context* context, const PaintOptions& options, DrawTypeFlags drawTypes) {
102 
103     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
104     const Caps* caps = context->priv().caps();
105 
106     auto rtEffectDict = std::make_unique<RuntimeEffectDictionary>();
107 
108     SkColorInfo ci(kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
109     KeyContext keyContext(
110             caps, dict, rtEffectDict.get(), ci, /* dstTexture= */ nullptr, /* dstOffset= */ {0, 0});
111 
112     for (Coverage coverage : { Coverage::kNone, Coverage::kSingleChannel, Coverage::kLCD }) {
113         PrecompileCombinations(
114                 context, options, keyContext,
115                 static_cast<DrawTypeFlags>(drawTypes & ~DrawTypeFlags::kDrawVertices),
116                 /* withPrimitiveBlender= */ false,
117                 coverage);
118     }
119 
120     if (drawTypes & DrawTypeFlags::kDrawVertices) {
121         for (Coverage coverage: { Coverage::kNone, Coverage::kSingleChannel, Coverage::kLCD }) {
122             // drawVertices w/ colors use a primitiveBlender while those w/o don't
123             for (bool withPrimitiveBlender : { true, false }) {
124                 PrecompileCombinations(context, options, keyContext,
125                                        DrawTypeFlags::kDrawVertices,
126                                        withPrimitiveBlender,
127                                        coverage);
128             }
129         }
130     }
131 }
132 
PrecompileCombinations(Context * context,const PaintOptions & options,const KeyContext & keyContext,DrawTypeFlags drawTypes,bool withPrimitiveBlender,Coverage coverage)133 void PrecompileCombinations(Context* context,
134                             const PaintOptions& options,
135                             const KeyContext& keyContext,
136                             DrawTypeFlags drawTypes,
137                             bool withPrimitiveBlender,
138                             Coverage coverage) {
139     const Caps* caps = keyContext.caps();
140     // Since the precompilation path's uniforms aren't used and don't change the key,
141     // the exact layout doesn't matter
142     PipelineDataGatherer gatherer(caps, Layout::kMetal);
143 
144     SkColorType destCT = keyContext.dstColorInfo().colorType();
145     // TODO: we need iterate over a broader set of TextureInfos here. Perhaps, allow the client
146     // to pass in colorType, mipmapping and protection.
147     TextureInfo info = caps->getDefaultSampledTextureInfo(destCT,
148                                                           Mipmapped::kNo,
149                                                           Protected::kNo,
150                                                           Renderable::kYes);
151 
152     Swizzle writeSwizzle = caps->getWriteSwizzle(destCT, info);
153     // Note: at least on Metal, the LoadOp, StoreOp and clearColor fields don't influence the
154     // actual RenderPassDescKey.
155     // TODO: if all of the Renderers associated w/ the requested drawTypes require MSAA we
156     // do not need to generate the combinations w/ the non-MSAA RenderPassDescs.
157     const RenderPassDesc renderPassDescs[] = {
158         RenderPassDesc::Make(caps,
159                              info,
160                              LoadOp::kClear,
161                              StoreOp::kStore,
162                              DepthStencilFlags::kDepth,
163                              /* clearColor= */ { .0f, .0f, .0f, .0f },
164                              /* requiresMSAA= */ true,
165                              writeSwizzle),
166         RenderPassDesc::Make(caps,
167                              info,
168                              LoadOp::kClear,
169                              StoreOp::kStore,
170                              DepthStencilFlags::kDepthStencil,
171                              /* clearColor= */ { .0f, .0f, .0f, .0f },
172                              /* requiresMSAA= */ true,
173                              writeSwizzle),
174         RenderPassDesc::Make(caps,
175                              info,
176                              LoadOp::kClear,
177                              StoreOp::kStore,
178                              DepthStencilFlags::kDepth,
179                              /* clearColor= */ { .0f, .0f, .0f, .0f },
180                              /* requiresMSAA= */ false,
181                              writeSwizzle),
182         RenderPassDesc::Make(caps,
183                              info,
184                              LoadOp::kClear,
185                              StoreOp::kStore,
186                              DepthStencilFlags::kDepthStencil,
187                              /* clearColor= */ { .0f, .0f, .0f, .0f },
188                              /* requiresMSAA= */ false,
189                              writeSwizzle),
190     };
191 
192     options.priv().buildCombinations(
193         keyContext,
194         &gatherer,
195         drawTypes,
196         withPrimitiveBlender,
197         coverage,
198         [context, &keyContext, &renderPassDescs](UniquePaintParamsID uniqueID,
199                                                  DrawTypeFlags drawTypes,
200                                                  bool withPrimitiveBlender,
201                                                  Coverage coverage) {
202                compile(context->priv().rendererProvider(),
203                        context->priv().resourceProvider(),
204                        keyContext,
205                        uniqueID,
206                        drawTypes,
207                        renderPassDescs,
208                        withPrimitiveBlender,
209                        coverage);
210         });
211 }
212 
213 } // namespace skgpu::graphite
214