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