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