• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #ifndef skgpu_GraphicsPipelineDesc_DEFINED
9 #define skgpu_GraphicsPipelineDesc_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 
13 #include "experimental/graphite/src/Attribute.h"
14 #include "experimental/graphite/src/DrawTypes.h"
15 #include "include/core/SkSpan.h"
16 #include "include/private/SkOpts_spi.h"
17 #include "include/private/SkTArray.h"
18 #include "include/private/SkUniquePaintParamsID.h"
19 
20 #include <array>
21 namespace skgpu {
22 
23 class RenderStep;
24 
25 /**
26  * GraphicsPipelineDesc represents the state needed to create a backend specific GraphicsPipeline,
27  * minus the target-specific properties that can be inferred from the DrawPass and RenderPassTask.
28  */
29 class GraphicsPipelineDesc {
30 public:
31     GraphicsPipelineDesc();
32 
asKey()33     SkSpan<const uint32_t> asKey() const { return SkMakeSpan(fKey.data(), fKey.size()); }
34 
35     bool operator==(const GraphicsPipelineDesc& that) const {
36         return this->fKey == that.fKey;
37     }
38 
39     bool operator!=(const GraphicsPipelineDesc& other) const {
40         return !(*this == other);
41     }
42 
43     // Describes the geometric portion of the pipeline's program and the pipeline's fixed state
44     // (except for renderpass-level state that will never change between draws).
renderStep()45     const RenderStep* renderStep() const { return fRenderStep; }
46     // UniqueID of the required PaintParams
paintParamsID()47     SkUniquePaintParamsID paintParamsID() const { return fUniqueID; }
48 
setProgram(const RenderStep * step,SkUniquePaintParamsID uniqueID)49     void setProgram(const RenderStep* step, SkUniquePaintParamsID uniqueID) {
50         SkASSERT(step);
51         fRenderStep = step;
52         fUniqueID = uniqueID;
53 
54         uintptr_t addr = reinterpret_cast<uintptr_t>(fRenderStep);
55         memcpy(fKey.data(), &addr, sizeof(uintptr_t));
56         fKey[kWords - 1] = fUniqueID.asUInt();
57     }
58 
59     struct Hash {
operatorHash60         uint32_t operator()(const GraphicsPipelineDesc& desc) const {
61             return SkOpts::hash_fn(desc.fKey.data(), desc.fKey.size() * sizeof(uint32_t), 0);
62         }
63     };
64 
65 private:
66     // The key is the RenderStep address and the uint32_t key from Combination
67     static constexpr int kWords = sizeof(uintptr_t) / sizeof(uint32_t) + 1;
68     static_assert(sizeof(uintptr_t) % sizeof(uint32_t) == 0);
69 
70     // TODO: I wonder if we could expose the "key" as just a char[] union over the renderstep and
71     // paint combination? That would avoid extra size, but definitely locks GraphicsPipelineDesc
72     // keys to the current process, which is probably okay since we can have something a with a more
73     // stable hash used for the pre-compilation combos.
74     std::array<uint32_t, kWords> fKey;
75 
76     // Each RenderStep defines a fixed set of attributes and rasterization state, as well as the
77     // shader fragments that control the geometry and coverage calculations. The RenderStep's shader
78     // is combined with the rest of the shader generated from the PaintParams. Because each
79     // RenderStep is fixed, its pointer can be used as a proxy for everything that it specifies in
80     // the GraphicsPipeline.
81     const RenderStep* fRenderStep = nullptr;
82 
83     SkUniquePaintParamsID fUniqueID;
84 };
85 
86 } // namespace skgpu
87 
88 #endif // skgpu_GraphicsPipelineDesc_DEFINED
89