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