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