/src/skia/src/gpu/ganesh/GrProgramDesc.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2016 Google Inc. |
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 | | #include "src/gpu/ganesh/GrProgramDesc.h" |
8 | | |
9 | | #include "include/gpu/ganesh/GrBackendSurface.h" |
10 | | #include "include/private/base/SkAssert.h" |
11 | | #include "include/private/base/SkTo.h" |
12 | | #include "include/private/gpu/ganesh/GrTypesPriv.h" |
13 | | #include "src/gpu/KeyBuilder.h" |
14 | | #include "src/gpu/Swizzle.h" |
15 | | #include "src/gpu/ganesh/GrCaps.h" |
16 | | #include "src/gpu/ganesh/GrFragmentProcessor.h" |
17 | | #include "src/gpu/ganesh/GrGeometryProcessor.h" |
18 | | #include "src/gpu/ganesh/GrPipeline.h" |
19 | | #include "src/gpu/ganesh/GrProcessor.h" |
20 | | #include "src/gpu/ganesh/GrProgramInfo.h" |
21 | | #include "src/gpu/ganesh/GrSurfaceProxy.h" |
22 | | #include "src/gpu/ganesh/GrSurfaceProxyView.h" |
23 | | #include "src/gpu/ganesh/GrXferProcessor.h" |
24 | | #include "src/gpu/ganesh/effects/GrTextureEffect.h" |
25 | | |
26 | | enum GrSurfaceOrigin : int; |
27 | | |
28 | | // Currently we allow 8 bits for the class id |
29 | | static constexpr uint32_t kClassIDBits = 8; |
30 | | static constexpr uint32_t kSamplerOrImageTypeKeyBits = 4; |
31 | | |
32 | 0 | static inline uint16_t texture_type_key(GrTextureType type) { |
33 | 0 | int value = UINT16_MAX; |
34 | 0 | switch (type) { |
35 | 0 | case GrTextureType::k2D: |
36 | 0 | value = 0; |
37 | 0 | break; |
38 | 0 | case GrTextureType::kExternal: |
39 | 0 | value = 1; |
40 | 0 | break; |
41 | 0 | case GrTextureType::kRectangle: |
42 | 0 | value = 2; |
43 | 0 | break; |
44 | 0 | default: |
45 | 0 | SK_ABORT("Unexpected texture type"); |
46 | 0 | value = 3; |
47 | 0 | break; |
48 | 0 | } |
49 | 0 | SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value); |
50 | 0 | return SkToU16(value); |
51 | 0 | } Unexecuted instantiation: GrProgramDesc.cpp:texture_type_key(GrTextureType) Unexecuted instantiation: GrProgramDesc.cpp:texture_type_key(GrTextureType) |
52 | | |
53 | | static uint32_t sampler_key(GrTextureType textureType, const skgpu::Swizzle& swizzle, |
54 | 0 | const GrCaps& caps) { |
55 | 0 | int samplerTypeKey = texture_type_key(textureType); |
56 | |
|
57 | 0 | static_assert(2 == sizeof(swizzle.asKey())); |
58 | 0 | uint16_t swizzleKey = swizzle.asKey(); |
59 | 0 | return SkToU32(samplerTypeKey | swizzleKey << kSamplerOrImageTypeKeyBits); |
60 | 0 | } |
61 | | |
62 | | static void add_geomproc_sampler_keys(skgpu::KeyBuilder* b, |
63 | | const GrGeometryProcessor& geomProc, |
64 | 0 | const GrCaps& caps) { |
65 | 0 | int numTextureSamplers = geomProc.numTextureSamplers(); |
66 | 0 | b->add32(numTextureSamplers, "ppNumSamplers"); |
67 | 0 | for (int i = 0; i < numTextureSamplers; ++i) { |
68 | 0 | const GrGeometryProcessor::TextureSampler& sampler = geomProc.textureSampler(i); |
69 | 0 | const GrBackendFormat& backendFormat = sampler.backendFormat(); |
70 | |
|
71 | 0 | uint32_t samplerKey = sampler_key(backendFormat.textureType(), sampler.swizzle(), caps); |
72 | 0 | b->add32(samplerKey); |
73 | |
|
74 | 0 | caps.addExtraSamplerKey(b, sampler.samplerState(), backendFormat); |
75 | 0 | } |
76 | 0 | } |
77 | | |
78 | | /** |
79 | | * Functions which emit processor key info into the key builder. |
80 | | * For every effect, we include the effect's class ID (different for every GrProcessor subclass), |
81 | | * any information generated by the effect itself (addToKey), and some meta-information. |
82 | | * Shader code may be dependent on properties of the effect not placed in the key by the effect |
83 | | * (e.g. pixel format of textures used). |
84 | | */ |
85 | | static void gen_geomproc_key(const GrGeometryProcessor& geomProc, |
86 | | const GrCaps& caps, |
87 | 0 | skgpu::KeyBuilder* b) { |
88 | 0 | b->appendComment(geomProc.name()); |
89 | 0 | b->addBits(kClassIDBits, geomProc.classID(), "geomProcClassID"); |
90 | |
|
91 | 0 | geomProc.addToKey(*caps.shaderCaps(), b); |
92 | 0 | geomProc.getAttributeKey(b); |
93 | |
|
94 | 0 | add_geomproc_sampler_keys(b, geomProc, caps); |
95 | 0 | } |
96 | | |
97 | | static void gen_xp_key(const GrXferProcessor& xp, |
98 | | const GrCaps& caps, |
99 | | const GrPipeline& pipeline, |
100 | 0 | skgpu::KeyBuilder* b) { |
101 | 0 | b->appendComment(xp.name()); |
102 | 0 | b->addBits(kClassIDBits, xp.classID(), "xpClassID"); |
103 | |
|
104 | 0 | const GrSurfaceOrigin* originIfDstTexture = nullptr; |
105 | 0 | GrSurfaceOrigin origin; |
106 | 0 | const GrSurfaceProxyView& dstView = pipeline.dstProxyView(); |
107 | 0 | if (dstView.proxy()) { |
108 | 0 | origin = dstView.origin(); |
109 | 0 | originIfDstTexture = &origin; |
110 | |
|
111 | 0 | uint32_t samplerKey = sampler_key(dstView.proxy()->backendFormat().textureType(), |
112 | 0 | dstView.swizzle(), caps); |
113 | 0 | b->add32(samplerKey); |
114 | 0 | } |
115 | |
|
116 | 0 | xp.addToKey(*caps.shaderCaps(), |
117 | 0 | b, |
118 | 0 | originIfDstTexture, |
119 | 0 | pipeline.dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment); |
120 | 0 | } |
121 | | |
122 | | static void gen_fp_key(const GrFragmentProcessor& fp, |
123 | | const GrCaps& caps, |
124 | 0 | skgpu::KeyBuilder* b) { |
125 | 0 | b->appendComment(fp.name()); |
126 | 0 | b->addBits(kClassIDBits, fp.classID(), "fpClassID"); |
127 | 0 | b->addBits(GrGeometryProcessor::kCoordTransformKeyBits, |
128 | 0 | GrGeometryProcessor::ComputeCoordTransformsKey(fp), "fpTransforms"); |
129 | |
|
130 | 0 | if (auto* te = fp.asTextureEffect()) { |
131 | 0 | const GrBackendFormat& backendFormat = te->view().proxy()->backendFormat(); |
132 | 0 | uint32_t samplerKey = sampler_key(backendFormat.textureType(), te->view().swizzle(), caps); |
133 | 0 | b->add32(samplerKey, "fpSamplerKey"); |
134 | 0 | caps.addExtraSamplerKey(b, te->samplerState(), backendFormat); |
135 | 0 | } |
136 | |
|
137 | 0 | fp.addToKey(*caps.shaderCaps(), b); |
138 | 0 | b->add32(fp.numChildProcessors(), "fpNumChildren"); |
139 | |
|
140 | 0 | for (int i = 0; i < fp.numChildProcessors(); ++i) { |
141 | 0 | if (auto child = fp.childProcessor(i)) { |
142 | 0 | gen_fp_key(*child, caps, b); |
143 | 0 | } else { |
144 | | // Fold in a sentinel value as the "class ID" for any null children |
145 | 0 | b->appendComment("Null"); |
146 | 0 | b->addBits(kClassIDBits, GrProcessor::ClassID::kNull_ClassID, "fpClassID"); |
147 | 0 | } |
148 | 0 | } |
149 | 0 | } |
150 | | |
151 | | static void gen_key(skgpu::KeyBuilder* b, |
152 | | const GrProgramInfo& programInfo, |
153 | 0 | const GrCaps& caps) { |
154 | 0 | gen_geomproc_key(programInfo.geomProc(), caps, b); |
155 | |
|
156 | 0 | const GrPipeline& pipeline = programInfo.pipeline(); |
157 | 0 | b->addBits(2, pipeline.numFragmentProcessors(), "numFPs"); |
158 | 0 | b->addBits(1, pipeline.numColorFragmentProcessors(), "numColorFPs"); |
159 | 0 | for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { |
160 | 0 | gen_fp_key(pipeline.getFragmentProcessor(i), caps, b); |
161 | 0 | } |
162 | |
|
163 | 0 | gen_xp_key(pipeline.getXferProcessor(), caps, pipeline, b); |
164 | |
|
165 | 0 | b->addBits(16, pipeline.writeSwizzle().asKey(), "writeSwizzle"); |
166 | 0 | b->addBool(pipeline.snapVerticesToPixelCenters(), "snapVertices"); |
167 | | // The base descriptor only stores whether or not the primitiveType is kPoints. Backend- |
168 | | // specific versions (e.g., Vulkan) require more detail |
169 | 0 | b->addBool((programInfo.primitiveType() == GrPrimitiveType::kPoints), "isPoints"); |
170 | | |
171 | | // Put a clean break between the "common" data written by this function, and any backend data |
172 | | // appended later. The initial key length will just be this portion (rounded to 4 bytes). |
173 | 0 | b->flush(); |
174 | 0 | } |
175 | | |
176 | | void GrProgramDesc::Build(GrProgramDesc* desc, |
177 | | const GrProgramInfo& programInfo, |
178 | 0 | const GrCaps& caps) { |
179 | 0 | desc->reset(); |
180 | 0 | skgpu::KeyBuilder b(desc->key()); |
181 | 0 | gen_key(&b, programInfo, caps); |
182 | 0 | desc->fInitialKeyLength = desc->keyLength(); |
183 | 0 | } |
184 | | |
185 | | SkString GrProgramDesc::Describe(const GrProgramInfo& programInfo, |
186 | 0 | const GrCaps& caps) { |
187 | 0 | GrProgramDesc desc; |
188 | 0 | skgpu::StringKeyBuilder b(desc.key()); |
189 | 0 | gen_key(&b, programInfo, caps); |
190 | 0 | b.flush(); |
191 | 0 | return b.description(); |
192 | 0 | } |