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