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