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 #ifndef GrVkUniformHandler_DEFINED 9 #define GrVkUniformHandler_DEFINED 10 11 #include "include/gpu/vk/GrVkTypes.h" 12 #include "src/core/SkTBlockList.h" 13 #include "src/gpu/GrSamplerState.h" 14 #include "src/gpu/GrShaderVar.h" 15 #include "src/gpu/glsl/GrGLSLProgramBuilder.h" 16 #include "src/gpu/glsl/GrGLSLUniformHandler.h" 17 #include "src/gpu/vk/GrVkSampler.h" 18 19 class GrVkUniformHandler : public GrGLSLUniformHandler { 20 public: 21 static const int kUniformsPerBlock = 8; 22 23 enum { 24 /** 25 * Binding a descriptor set invalidates all higher index descriptor sets. We must bind 26 * in the order of this enumeration. Samplers are after Uniforms because GrOps can specify 27 * GP textures as dynamic state, meaning they get rebound for each draw in a pipeline while 28 * uniforms are bound once before all the draws. We bind input attachments after samplers 29 * so those also need to be rebound if we bind new samplers. 30 */ 31 kUniformBufferDescSet = 0, 32 kSamplerDescSet = 1, 33 kInputDescSet = 2, 34 35 kLastDescSet = kInputDescSet, 36 }; 37 static constexpr int kDescSetCount = kLastDescSet + 1; 38 39 // The bindings within their respective sets for various descriptor types. 40 enum { 41 kUniformBinding = 0, 42 kInputBinding = 0, 43 }; 44 enum { 45 kDstInputAttachmentIndex = 0 46 }; 47 48 // The two types of memory layout we're concerned with 49 enum Layout { 50 kStd140Layout = 0, 51 kStd430Layout = 1, 52 53 kLastLayout = kStd430Layout 54 }; 55 static constexpr int kLayoutCount = kLastLayout + 1; 56 57 struct VkUniformInfo : public UniformInfo { 58 // offsets are only valid if the GrSLType of the fVariable is not a sampler. 59 uint32_t fOffsets[kLayoutCount]; 60 // fImmutableSampler is used for sampling an image with a ycbcr conversion. 61 const GrVkSampler* fImmutableSampler = nullptr; 62 }; 63 typedef SkTBlockList<VkUniformInfo> UniformInfoArray; 64 65 ~GrVkUniformHandler() override; 66 getUniformVariable(UniformHandle u)67 const GrShaderVar& getUniformVariable(UniformHandle u) const override { 68 return fUniforms.item(u.toIndex()).fVariable; 69 } 70 getUniformCStr(UniformHandle u)71 const char* getUniformCStr(UniformHandle u) const override { 72 return this->getUniformVariable(u).c_str(); 73 } 74 75 /** 76 * Returns the offset that the RTFlip synthetic uniform should use if it needs to be created. 77 */ 78 uint32_t getRTFlipOffset() const; 79 numUniforms()80 int numUniforms() const override { 81 return fUniforms.count(); 82 } 83 uniform(int idx)84 UniformInfo& uniform(int idx) override { 85 return fUniforms.item(idx); 86 } uniform(int idx)87 const UniformInfo& uniform(int idx) const override { 88 return fUniforms.item(idx); 89 } 90 usePushConstants()91 bool usePushConstants() const { return fUsePushConstants; } currentOffset()92 uint32_t currentOffset() const { 93 return fUsePushConstants ? fCurrentOffsets[kStd430Layout] : fCurrentOffsets[kStd140Layout]; 94 } 95 96 private: GrVkUniformHandler(GrGLSLProgramBuilder * program)97 explicit GrVkUniformHandler(GrGLSLProgramBuilder* program) 98 : INHERITED(program) 99 , fUniforms(kUniformsPerBlock) 100 , fSamplers(kUniformsPerBlock) 101 , fUsePushConstants(false) 102 , fCurrentOffsets{0, 0} { 103 } 104 105 UniformHandle internalAddUniformArray(const GrFragmentProcessor* owner, 106 uint32_t visibility, 107 GrSLType type, 108 const char* name, 109 bool mangleName, 110 int arrayCount, 111 const char** outName) override; 112 113 SamplerHandle addSampler(const GrBackendFormat&, 114 GrSamplerState, 115 const GrSwizzle&, 116 const char* name, 117 const GrShaderCaps*) override; 118 119 SamplerHandle addInputSampler(const GrSwizzle& swizzle, const char* name) override; 120 numSamplers()121 int numSamplers() const { return fSamplers.count(); } samplerVariable(SamplerHandle handle)122 const char* samplerVariable(SamplerHandle handle) const override { 123 return fSamplers.item(handle.toIndex()).fVariable.c_str(); 124 } samplerSwizzle(SamplerHandle handle)125 GrSwizzle samplerSwizzle(SamplerHandle handle) const override { 126 return fSamplerSwizzles[handle.toIndex()]; 127 } samplerVisibility(SamplerHandle handle)128 uint32_t samplerVisibility(SamplerHandle handle) const { 129 return fSamplers.item(handle.toIndex()).fVisibility; 130 } 131 immutableSampler(UniformHandle u)132 const GrVkSampler* immutableSampler(UniformHandle u) const { 133 return fSamplers.item(u.toIndex()).fImmutableSampler; 134 } 135 inputSamplerVariable(SamplerHandle handle)136 const char* inputSamplerVariable(SamplerHandle handle) const override { 137 // Currently we will only ever have one input sampler variable, though in the future we may 138 // expand to allow more inputs. For now assert that any requested handle maps to index 0, 139 // to make sure we didn't add multiple input samplers. 140 SkASSERT(handle.toIndex() == 0); 141 return fInputUniform.fVariable.c_str(); 142 } inputSamplerSwizzle(SamplerHandle handle)143 GrSwizzle inputSamplerSwizzle(SamplerHandle handle) const override { 144 SkASSERT(handle.toIndex() == 0); 145 return fInputSwizzle; 146 } 147 148 void appendUniformDecls(GrShaderFlags, SkString*) const override; 149 getUniformInfo(UniformHandle u)150 const VkUniformInfo& getUniformInfo(UniformHandle u) const { 151 return fUniforms.item(u.toIndex()); 152 } 153 154 void determineIfUsePushConstants() const; 155 156 UniformInfoArray fUniforms; 157 UniformInfoArray fSamplers; 158 SkTArray<GrSwizzle> fSamplerSwizzles; 159 UniformInfo fInputUniform; 160 GrSwizzle fInputSwizzle; 161 mutable bool fUsePushConstants; 162 163 uint32_t fCurrentOffsets[kLayoutCount]; 164 165 friend class GrVkPipelineStateBuilder; 166 friend class GrVkDescriptorSetManager; 167 168 using INHERITED = GrGLSLUniformHandler; 169 }; 170 171 #endif 172