• 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/gpu/GrSamplerState.h"
13 #include "src/gpu/GrShaderVar.h"
14 #include "src/gpu/GrTBlockList.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 GrTBlockList<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 RTHeight synthetic uniform should use if it needs to be created.
77      */
78     uint32_t getRTHeightOffset() 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 
getFlipY()91     bool getFlipY() const { return fFlipY; }
92 
usePushConstants()93     bool usePushConstants() const { return fUsePushConstants; }
currentOffset()94     uint32_t currentOffset() const {
95         return fUsePushConstants ? fCurrentOffsets[kStd430Layout] : fCurrentOffsets[kStd140Layout];
96     }
97 
98 private:
GrVkUniformHandler(GrGLSLProgramBuilder * program)99     explicit GrVkUniformHandler(GrGLSLProgramBuilder* program)
100         : INHERITED(program)
101         , fUniforms(kUniformsPerBlock)
102         , fSamplers(kUniformsPerBlock)
103         , fFlipY(program->origin() != kTopLeft_GrSurfaceOrigin)
104         , fUsePushConstants(false)
105         , fCurrentOffsets{0, 0} {
106     }
107 
108     UniformHandle internalAddUniformArray(const GrFragmentProcessor* owner,
109                                           uint32_t visibility,
110                                           GrSLType 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 GrSwizzle&,
119                              const char* name,
120                              const GrShaderCaps*) override;
121 
122     SamplerHandle addInputSampler(const GrSwizzle& 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     GrSwizzle 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     GrSwizzle 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     SkTArray<GrSwizzle> fSamplerSwizzles;
162     UniformInfo         fInputUniform;
163     GrSwizzle           fInputSwizzle;
164     bool                fFlipY;
165     mutable bool        fUsePushConstants;
166 
167     uint32_t            fCurrentOffsets[kLayoutCount];
168 
169     friend class GrVkPipelineStateBuilder;
170     friend class GrVkDescriptorSetManager;
171 
172     using INHERITED = GrGLSLUniformHandler;
173 };
174 
175 #endif
176