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 "GrProgramDesc.h" 8 #include "GrPipeline.h" 9 #include "GrPrimitiveProcessor.h" 10 #include "GrProcessor.h" 11 #include "GrRenderTargetPriv.h" 12 #include "GrShaderCaps.h" 13 #include "GrTexturePriv.h" 14 #include "SkChecksum.h" 15 #include "glsl/GrGLSLFragmentProcessor.h" 16 #include "glsl/GrGLSLFragmentShaderBuilder.h" 17 18 enum { 19 kSamplerOrImageTypeKeyBits = 4 20 }; 21 22 static inline uint16_t image_storage_or_sampler_uniform_type_key(GrSLType type ) { 23 int value = UINT16_MAX; 24 switch (type) { 25 case kTexture2DSampler_GrSLType: 26 value = 0; 27 break; 28 case kITexture2DSampler_GrSLType: 29 value = 1; 30 break; 31 case kTextureExternalSampler_GrSLType: 32 value = 2; 33 break; 34 case kTexture2DRectSampler_GrSLType: 35 value = 3; 36 break; 37 case kBufferSampler_GrSLType: 38 value = 4; 39 break; 40 41 default: 42 break; 43 } 44 SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value); 45 return value; 46 } 47 48 static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility, 49 const GrShaderCaps& caps) { 50 int samplerTypeKey = image_storage_or_sampler_uniform_type_key(samplerType); 51 52 GR_STATIC_ASSERT(1 == sizeof(caps.configTextureSwizzle(config).asKey())); 53 return SkToU16(samplerTypeKey | 54 caps.configTextureSwizzle(config).asKey() << kSamplerOrImageTypeKeyBits | 55 (GrSLSamplerPrecision(config) << (8 + kSamplerOrImageTypeKeyBits))); 56 } 57 58 static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourceIOProcessor& proc, 59 const GrShaderCaps& caps) { 60 int numTextureSamplers = proc.numTextureSamplers(); 61 int numBuffers = proc.numBuffers(); 62 int numUniforms = numTextureSamplers + numBuffers; 63 // Need two bytes per key. 64 int word32Count = (numUniforms + 1) / 2; 65 if (0 == word32Count) { 66 return; 67 } 68 uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count)); 69 int j = 0; 70 for (int i = 0; i < numTextureSamplers; ++i, ++j) { 71 const GrResourceIOProcessor::TextureSampler& sampler = proc.textureSampler(i); 72 const GrTexture* tex = sampler.peekTexture(); 73 74 k16[j] = sampler_key(tex->texturePriv().samplerType(), tex->config(), sampler.visibility(), 75 caps); 76 } 77 for (int i = 0; i < numBuffers; ++i, ++j) { 78 const GrResourceIOProcessor::BufferAccess& access = proc.bufferAccess(i); 79 k16[j] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(), access.visibility(), 80 caps); 81 } 82 // zero the last 16 bits if the number of uniforms for samplers and image storages is odd. 83 if (numUniforms & 0x1) { 84 k16[numUniforms] = 0; 85 } 86 } 87 88 /** 89 * A function which emits a meta key into the key builder. This is required because shader code may 90 * be dependent on properties of the effect that the effect itself doesn't use 91 * in its key (e.g. the pixel format of textures used). So we create a meta-key for 92 * every effect using this function. It is also responsible for inserting the effect's class ID 93 * which must be different for every GrProcessor subclass. It can fail if an effect uses too many 94 * transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share this 95 * function because it is hairy, though FPs do not have attribs, and GPs do not have transforms 96 */ 97 static bool gen_meta_key(const GrResourceIOProcessor& proc, 98 const GrShaderCaps& shaderCaps, 99 uint32_t transformKey, 100 GrProcessorKeyBuilder* b) { 101 size_t processorKeySize = b->size(); 102 uint32_t classID = proc.classID(); 103 104 // Currently we allow 16 bits for the class id and the overall processor key size. 105 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)SK_MaxU16); 106 if ((processorKeySize | classID) & kMetaKeyInvalidMask) { 107 return false; 108 } 109 110 add_sampler_and_image_keys(b, proc, shaderCaps); 111 112 uint32_t* key = b->add32n(2); 113 key[0] = (classID << 16) | SkToU32(processorKeySize); 114 key[1] = transformKey; 115 return true; 116 } 117 118 static bool gen_meta_key(const GrXferProcessor& xp, 119 const GrShaderCaps& shaderCaps, 120 GrProcessorKeyBuilder* b) { 121 size_t processorKeySize = b->size(); 122 uint32_t classID = xp.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)SK_MaxU16); 126 if ((processorKeySize | classID) & kMetaKeyInvalidMask) { 127 return false; 128 } 129 130 b->add32((classID << 16) | SkToU32(processorKeySize)); 131 return true; 132 } 133 134 static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, 135 const GrFragmentProcessor& fp, 136 const GrShaderCaps& shaderCaps, 137 GrProcessorKeyBuilder* b) { 138 for (int i = 0; i < fp.numChildProcessors(); ++i) { 139 if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), shaderCaps, b)) { 140 return false; 141 } 142 } 143 144 fp.getGLSLProcessorKey(shaderCaps, b); 145 146 return gen_meta_key(fp, shaderCaps, primProc.getTransformKey(fp.coordTransforms(), 147 fp.numCoordTransforms()), b); 148 } 149 150 bool GrProgramDesc::Build(GrProgramDesc* desc, 151 const GrPrimitiveProcessor& primProc, 152 bool hasPointSize, 153 const GrPipeline& pipeline, 154 const GrShaderCaps& shaderCaps) { 155 // The descriptor is used as a cache key. Thus when a field of the 156 // descriptor will not affect program generation (because of the attribute 157 // bindings in use or other descriptor field settings) it should be set 158 // to a canonical value to avoid duplicate programs with different keys. 159 160 GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); 161 // Make room for everything up to the effect keys. 162 desc->key().reset(); 163 desc->key().push_back_n(kProcessorKeysOffset); 164 165 GrProcessorKeyBuilder b(&desc->key()); 166 167 primProc.getGLSLProcessorKey(shaderCaps, &b); 168 if (!gen_meta_key(primProc, shaderCaps, 0, &b)) { 169 desc->key().reset(); 170 return false; 171 } 172 GrProcessor::RequiredFeatures requiredFeatures = primProc.requiredFeatures(); 173 174 for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) { 175 const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i); 176 if (!gen_frag_proc_and_meta_keys(primProc, fp, shaderCaps, &b)) { 177 desc->key().reset(); 178 return false; 179 } 180 requiredFeatures |= fp.requiredFeatures(); 181 } 182 183 const GrXferProcessor& xp = pipeline.getXferProcessor(); 184 const GrSurfaceOrigin* originIfDstTexture = nullptr; 185 GrSurfaceOrigin origin; 186 if (pipeline.dstTextureProxy()) { 187 origin = pipeline.dstTextureProxy()->origin(); 188 originIfDstTexture = &origin; 189 } 190 xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture); 191 if (!gen_meta_key(xp, shaderCaps, &b)) { 192 desc->key().reset(); 193 return false; 194 } 195 requiredFeatures |= xp.requiredFeatures(); 196 197 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------------------------- 198 // Because header is a pointer into the dynamic array, we can't push any new data into the key 199 // below here. 200 KeyHeader* header = desc->atOffset<KeyHeader, kHeaderOffset>(); 201 202 // make sure any padding in the header is zeroed. 203 memset(header, 0, kHeaderSize); 204 205 GrRenderTargetProxy* proxy = pipeline.proxy(); 206 207 if (requiredFeatures & GrProcessor::kSampleLocations_RequiredFeature) { 208 SkASSERT(pipeline.isHWAntialiasState()); 209 210 GrRenderTarget* rt = pipeline.renderTarget(); 211 header->fSamplePatternKey = 212 rt->renderTargetPriv().getMultisampleSpecs(pipeline).fUniqueID; 213 } else { 214 header->fSamplePatternKey = 0; 215 } 216 217 header->fOutputSwizzle = shaderCaps.configOutputSwizzle(proxy->config()).asKey(); 218 219 header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters(); 220 header->fColorFragmentProcessorCnt = pipeline.numColorFragmentProcessors(); 221 header->fCoverageFragmentProcessorCnt = pipeline.numCoverageFragmentProcessors(); 222 // Fail if the client requested more processors than the key can fit. 223 if (header->fColorFragmentProcessorCnt != pipeline.numColorFragmentProcessors() || 224 header->fCoverageFragmentProcessorCnt != pipeline.numCoverageFragmentProcessors()) { 225 return false; 226 } 227 header->fHasPointSize = hasPointSize ? 1 : 0; 228 return true; 229 } 230