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 
8 #include "src/gpu/GrProgramDesc.h"
9 
10 #include "include/private/SkChecksum.h"
11 #include "include/private/SkTo.h"
12 #include "src/gpu/GrPipeline.h"
13 #include "src/gpu/GrPrimitiveProcessor.h"
14 #include "src/gpu/GrProcessor.h"
15 #include "src/gpu/GrProgramInfo.h"
16 #include "src/gpu/GrRenderTargetPriv.h"
17 #include "src/gpu/GrShaderCaps.h"
18 #include "src/gpu/GrTexturePriv.h"
19 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
20 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
21 
22 enum {
23     kSamplerOrImageTypeKeyBits = 4
24 };
25 
texture_type_key(GrTextureType type)26 static inline uint16_t texture_type_key(GrTextureType type) {
27     int value = UINT16_MAX;
28     switch (type) {
29         case GrTextureType::k2D:
30             value = 0;
31             break;
32         case GrTextureType::kExternal:
33             value = 1;
34             break;
35         case GrTextureType::kRectangle:
36             value = 2;
37             break;
38         default:
39             SK_ABORT("Unexpected texture type");
40             value = 3;
41             break;
42     }
43     SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value);
44     return SkToU16(value);
45 }
46 
sampler_key(GrTextureType textureType,const GrSwizzle & swizzle,const GrShaderCaps & caps)47 static uint32_t sampler_key(GrTextureType textureType, const GrSwizzle& swizzle,
48                             const GrShaderCaps& caps) {
49     int samplerTypeKey = texture_type_key(textureType);
50 
51     GR_STATIC_ASSERT(2 == sizeof(swizzle.asKey()));
52     uint16_t swizzleKey = 0;
53     if (caps.textureSwizzleAppliedInShader()) {
54         swizzleKey = swizzle.asKey();
55     }
56     return SkToU32(samplerTypeKey | swizzleKey << kSamplerOrImageTypeKeyBits);
57 }
58 
add_sampler_keys(GrProcessorKeyBuilder * b,const GrFragmentProcessor & fp,GrGpu * gpu,const GrShaderCaps & caps)59 static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrFragmentProcessor& fp,
60                              GrGpu* gpu, const GrShaderCaps& caps) {
61     int numTextureSamplers = fp.numTextureSamplers();
62     if (!numTextureSamplers) {
63         return;
64     }
65     for (int i = 0; i < numTextureSamplers; ++i) {
66         const GrFragmentProcessor::TextureSampler& sampler = fp.textureSampler(i);
67         const GrTexture* tex = sampler.peekTexture();
68         uint32_t samplerKey = sampler_key(
69                 tex->texturePriv().textureType(), sampler.swizzle(), caps);
70         uint32_t extraSamplerKey = gpu->getExtraSamplerKeyForProgram(
71                 sampler.samplerState(), sampler.proxy()->backendFormat());
72         if (extraSamplerKey) {
73             // We first mark the normal sampler key with last bit to flag that it has an extra
74             // sampler key. We then add both keys.
75             SkASSERT((samplerKey & (1 << 31)) == 0);
76             b->add32(samplerKey | (1 << 31));
77             b->add32(extraSamplerKey);
78         } else {
79             b->add32(samplerKey);
80         }
81     }
82 }
83 
add_sampler_keys(GrProcessorKeyBuilder * b,const GrPrimitiveProcessor & pp,const GrShaderCaps & caps)84 static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrPrimitiveProcessor& pp,
85                              const GrShaderCaps& caps) {
86     int numTextureSamplers = pp.numTextureSamplers();
87     if (!numTextureSamplers) {
88         return;
89     }
90     for (int i = 0; i < numTextureSamplers; ++i) {
91         const GrPrimitiveProcessor::TextureSampler& sampler = pp.textureSampler(i);
92         uint32_t samplerKey = sampler_key(
93                 sampler.textureType(), sampler.swizzle(), caps);
94         uint32_t extraSamplerKey = sampler.extraSamplerKey();
95         if (extraSamplerKey) {
96             // We first mark the normal sampler key with last bit to flag that it has an extra
97             // sampler key. We then add both keys.
98             SkASSERT((samplerKey & (1 << 31)) == 0);
99             b->add32(samplerKey | (1 << 31));
100             b->add32(extraSamplerKey);
101         } else {
102             b->add32(samplerKey);
103         }
104     }
105 }
106 
107 /**
108  * A function which emits a meta key into the key builder.  This is required because shader code may
109  * be dependent on properties of the effect that the effect itself doesn't use
110  * in its key (e.g. the pixel format of textures used). So we create a meta-key for
111  * every effect using this function. It is also responsible for inserting the effect's class ID
112  * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
113  * transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share this
114  * function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
115  */
gen_meta_key(const GrFragmentProcessor & fp,GrGpu * gpu,const GrShaderCaps & shaderCaps,uint32_t transformKey,GrProcessorKeyBuilder * b)116 static bool gen_meta_key(const GrFragmentProcessor& fp,
117                          GrGpu* gpu,
118                          const GrShaderCaps& shaderCaps,
119                          uint32_t transformKey,
120                          GrProcessorKeyBuilder* b) {
121     size_t processorKeySize = b->size();
122     uint32_t classID = fp.classID();
123 
124     // Currently we allow 16 bits for the class id and the overall processor key size.
125     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)UINT16_MAX);
126     if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
127         return false;
128     }
129 
130     add_sampler_keys(b, fp, gpu, shaderCaps);
131 
132     uint32_t* key = b->add32n(2);
133     key[0] = (classID << 16) | SkToU32(processorKeySize);
134     key[1] = transformKey;
135     return true;
136 }
137 
gen_meta_key(const GrPrimitiveProcessor & pp,const GrShaderCaps & shaderCaps,uint32_t transformKey,GrProcessorKeyBuilder * b)138 static bool gen_meta_key(const GrPrimitiveProcessor& pp,
139                          const GrShaderCaps& shaderCaps,
140                          uint32_t transformKey,
141                          GrProcessorKeyBuilder* b) {
142     size_t processorKeySize = b->size();
143     uint32_t classID = pp.classID();
144 
145     // Currently we allow 16 bits for the class id and the overall processor key size.
146     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)UINT16_MAX);
147     if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
148         return false;
149     }
150 
151     add_sampler_keys(b, pp, shaderCaps);
152 
153     uint32_t* key = b->add32n(2);
154     key[0] = (classID << 16) | SkToU32(processorKeySize);
155     key[1] = transformKey;
156     return true;
157 }
158 
gen_meta_key(const GrXferProcessor & xp,const GrShaderCaps & shaderCaps,GrProcessorKeyBuilder * b)159 static bool gen_meta_key(const GrXferProcessor& xp,
160                          const GrShaderCaps& shaderCaps,
161                          GrProcessorKeyBuilder* b) {
162     size_t processorKeySize = b->size();
163     uint32_t classID = xp.classID();
164 
165     // Currently we allow 16 bits for the class id and the overall processor key size.
166     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)UINT16_MAX);
167     if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
168         return false;
169     }
170 
171     b->add32((classID << 16) | SkToU32(processorKeySize));
172     return true;
173 }
174 
gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor & primProc,const GrFragmentProcessor & fp,GrGpu * gpu,const GrShaderCaps & shaderCaps,GrProcessorKeyBuilder * b)175 static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
176                                         const GrFragmentProcessor& fp,
177                                         GrGpu* gpu,
178                                         const GrShaderCaps& shaderCaps,
179                                         GrProcessorKeyBuilder* b) {
180     for (int i = 0; i < fp.numChildProcessors(); ++i) {
181         if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), gpu, shaderCaps, b)) {
182             return false;
183         }
184     }
185 
186     fp.getGLSLProcessorKey(shaderCaps, b);
187 
188     return gen_meta_key(fp, gpu, shaderCaps, primProc.getTransformKey(fp.coordTransforms(),
189                                                                       fp.numCoordTransforms()), b);
190 }
191 
Build(GrProgramDesc * desc,const GrRenderTarget * renderTarget,const GrProgramInfo & programInfo,GrPrimitiveType primitiveType,GrGpu * gpu)192 bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarget,
193                           const GrProgramInfo& programInfo, GrPrimitiveType primitiveType,
194                           GrGpu* gpu) {
195     // The descriptor is used as a cache key. Thus when a field of the
196     // descriptor will not affect program generation (because of the attribute
197     // bindings in use or other descriptor field settings) it should be set
198     // to a canonical value to avoid duplicate programs with different keys.
199 
200     const GrShaderCaps& shaderCaps = *gpu->caps()->shaderCaps();
201 
202     GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t));
203     // Make room for everything up to the effect keys.
204     desc->key().reset();
205     desc->key().push_back_n(kProcessorKeysOffset);
206 
207     GrProcessorKeyBuilder b(&desc->key());
208 
209     programInfo.primProc().getGLSLProcessorKey(shaderCaps, &b);
210     programInfo.primProc().getAttributeKey(&b);
211     if (!gen_meta_key(programInfo.primProc(), shaderCaps, 0, &b)) {
212         desc->key().reset();
213         return false;
214     }
215 
216     for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
217         const GrFragmentProcessor& fp = programInfo.pipeline().getFragmentProcessor(i);
218         if (!gen_frag_proc_and_meta_keys(programInfo.primProc(), fp, gpu, shaderCaps, &b)) {
219             desc->key().reset();
220             return false;
221         }
222     }
223 
224     const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
225     const GrSurfaceOrigin* originIfDstTexture = nullptr;
226     GrSurfaceOrigin origin;
227     if (programInfo.pipeline().dstTextureProxy()) {
228         origin = programInfo.pipeline().dstTextureProxy()->origin();
229         originIfDstTexture = &origin;
230     }
231     xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture);
232     if (!gen_meta_key(xp, shaderCaps, &b)) {
233         desc->key().reset();
234         return false;
235     }
236 
237     if (programInfo.requestedFeatures() & GrProcessor::CustomFeatures::kSampleLocations) {
238         SkASSERT(programInfo.pipeline().isHWAntialiasState());
239         b.add32(renderTarget->renderTargetPriv().getSamplePatternKey());
240     }
241 
242     // --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
243     // Because header is a pointer into the dynamic array, we can't push any new data into the key
244     // below here.
245     KeyHeader* header = desc->atOffset<KeyHeader, kHeaderOffset>();
246 
247     // make sure any padding in the header is zeroed.
248     memset(header, 0, kHeaderSize);
249     header->fOutputSwizzle = programInfo.pipeline().outputSwizzle().asKey();
250     header->fColorFragmentProcessorCnt = programInfo.pipeline().numColorFragmentProcessors();
251     header->fCoverageFragmentProcessorCnt = programInfo.pipeline().numCoverageFragmentProcessors();
252     // Fail if the client requested more processors than the key can fit.
253     if (header->fColorFragmentProcessorCnt != programInfo.pipeline().numColorFragmentProcessors() ||
254         header->fCoverageFragmentProcessorCnt !=
255                                          programInfo.pipeline().numCoverageFragmentProcessors()) {
256         return false;
257     }
258     // If we knew the shader won't depend on origin, we could skip this (and use the same program
259     // for both origins). Instrumenting all fragment processors would be difficult and error prone.
260     header->fSurfaceOriginKey =
261                     GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin());
262     header->fProcessorFeatures = (uint8_t)programInfo.requestedFeatures();
263     // Ensure enough bits.
264     SkASSERT(header->fProcessorFeatures == (int) programInfo.requestedFeatures());
265     header->fSnapVerticesToPixelCenters = programInfo.pipeline().snapVerticesToPixelCenters();
266     header->fHasPointSize = (primitiveType == GrPrimitiveType::kPoints);
267     return true;
268 }
269