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