• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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