• 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 
9 #ifndef GrVkPipelineState_DEFINED
10 #define GrVkPipelineState_DEFINED
11 
12 #include "GrProgramDesc.h"
13 #include "GrStencilSettings.h"
14 #include "GrVkDescriptorSetManager.h"
15 #include "GrVkImage.h"
16 #include "GrVkPipelineStateDataManager.h"
17 #include "glsl/GrGLSLProgramBuilder.h"
18 
19 #include "vk/GrVkDefines.h"
20 
21 class GrPipeline;
22 class GrVkBufferView;
23 class GrVkCommandBuffer;
24 class GrVkDescriptorPool;
25 class GrVkDescriptorSet;
26 class GrVkGpu;
27 class GrVkImageView;
28 class GrVkPipeline;
29 class GrVkSampler;
30 class GrVkUniformBuffer;
31 
32 /**
33  * This class holds onto a GrVkPipeline object that we use for draws. Besides storing the acutal
34  * GrVkPipeline object, this class is also responsible handling all uniforms, descriptors, samplers,
35  * and other similar objects that are used along with the VkPipeline in the draw. This includes both
36  * allocating and freeing these objects, as well as updating their values.
37  */
38 class GrVkPipelineState : public SkRefCnt {
39 public:
40     typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
41 
42     ~GrVkPipelineState();
43 
vkPipeline()44     GrVkPipeline* vkPipeline() const { return fPipeline; }
45 
46     void setData(GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&);
47 
48     void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
49 
50     void addUniformResources(GrVkCommandBuffer&);
51 
52     void freeGPUResources(const GrVkGpu* gpu);
53 
54     // This releases resources that only a given instance of a GrVkPipelineState needs to hold onto
55     // and don't need to survive across new uses of the GrVkPipelineState.
56     void freeTempResources(const GrVkGpu* gpu);
57 
58     void abandonGPUResources();
59 
60     /**
61      * For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all
62      * the information needed to differentiate one pipeline from another.
63      *
64      * The GrProgramDesc contains all the information need to create the actual shaders for the
65      * pipeline.
66      *
67      * For Vulkan we need to add to the GrProgramDesc to include the rest of the state on the
68      * pipline. This includes stencil settings, blending information, render pass format, draw face
69      * information, and primitive type. Note that some state is set dynamically on the pipeline for
70      * each draw  and thus is not included in this descriptor. This includes the viewport, scissor,
71      * and blend constant.
72      */
73     class Desc : public GrProgramDesc {
74     public:
75         static bool Build(Desc*,
76                           const GrPrimitiveProcessor&,
77                           const GrPipeline&,
78                           const GrStencilSettings&,
79                           GrPrimitiveType primitiveType,
80                           const GrShaderCaps&);
81     private:
82         typedef GrProgramDesc INHERITED;
83     };
84 
getDesc()85     const Desc& getDesc() { return fDesc; }
86 
87 private:
88     typedef GrVkPipelineStateDataManager::UniformInfoArray UniformInfoArray;
89     typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
90 
91     GrVkPipelineState(GrVkGpu* gpu,
92                       const GrVkPipelineState::Desc&,
93                       GrVkPipeline* pipeline,
94                       VkPipelineLayout layout,
95                       const GrVkDescriptorSetManager::Handle& samplerDSHandle,
96                       const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
97                       const BuiltinUniformHandles& builtinUniformHandles,
98                       const UniformInfoArray& uniforms,
99                       uint32_t geometryUniformSize,
100                       uint32_t fragmentUniformSize,
101                       uint32_t numSamplers,
102                       uint32_t numTexelBuffers,
103                       GrGLSLPrimitiveProcessor* geometryProcessor,
104                       GrGLSLXferProcessor* xferProcessor,
105                       const GrGLSLFragProcs& fragmentProcessors);
106 
107     void writeUniformBuffers(const GrVkGpu* gpu);
108 
109     void writeSamplers(
110             GrVkGpu* gpu,
111             const SkTArray<const GrResourceIOProcessor::TextureSampler*>& textureBindings,
112             bool allowSRGBInputs);
113 
114     void writeTexelBuffers(
115             GrVkGpu* gpu,
116             const SkTArray<const GrResourceIOProcessor::BufferAccess*>& bufferAccesses);
117 
118     /**
119     * We use the RT's size and origin to adjust from Skia device space to vulkan normalized device
120     * space and to make device space positions have the correct origin for processors that require
121     * them.
122     */
123     struct RenderTargetState {
124         SkISize         fRenderTargetSize;
125         GrSurfaceOrigin fRenderTargetOrigin;
126 
RenderTargetStateRenderTargetState127         RenderTargetState() { this->invalidate(); }
invalidateRenderTargetState128         void invalidate() {
129             fRenderTargetSize.fWidth = -1;
130             fRenderTargetSize.fHeight = -1;
131             fRenderTargetOrigin = (GrSurfaceOrigin)-1;
132         }
133 
134         /**
135         * Gets a vec4 that adjusts the position from Skia device coords to Vulkans normalized device
136         * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
137         * applied as such:
138         * pos.x = dot(v.xy, pos.xz)
139         * pos.y = dot(v.zw, pos.yz)
140         */
getRTAdjustmentVecRenderTargetState141         void getRTAdjustmentVec(float* destVec) {
142             destVec[0] = 2.f / fRenderTargetSize.fWidth;
143             destVec[1] = -1.f;
144             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
145                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
146                 destVec[3] = 1.f;
147             } else {
148                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
149                 destVec[3] = -1.f;
150             }
151         }
152     };
153 
154     // Helper for setData() that sets the view matrix and loads the render target height uniform
155     void setRenderTargetState(const GrRenderTarget*);
156 
157     // GrVkResources
158     GrVkPipeline* fPipeline;
159 
160     // Used for binding DescriptorSets to the command buffer but does not need to survive during
161     // command buffer execution. Thus this is not need to be a GrVkResource.
162     VkPipelineLayout fPipelineLayout;
163 
164     // The DescriptorSets need to survive until the gpu has finished all draws that use them.
165     // However, they will only be freed by the descriptor pool. Thus by simply keeping the
166     // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do
167     // not need a GrVkResource versions of VkDescriptorSet. We hold on to these in the
168     // GrVkPipelineState since we update the descriptor sets and bind them at separate times;
169     VkDescriptorSet fDescriptorSets[3];
170 
171     const GrVkDescriptorSet* fUniformDescriptorSet;
172     const GrVkDescriptorSet* fSamplerDescriptorSet;
173     const GrVkDescriptorSet* fTexelBufferDescriptorSet;
174 
175     const GrVkDescriptorSetManager::Handle fSamplerDSHandle;
176     const GrVkDescriptorSetManager::Handle fTexelBufferDSHandle;
177 
178     std::unique_ptr<GrVkUniformBuffer> fGeometryUniformBuffer;
179     std::unique_ptr<GrVkUniformBuffer> fFragmentUniformBuffer;
180 
181     // GrVkResources used for sampling textures
182     SkTDArray<GrVkSampler*> fSamplers;
183     SkTDArray<const GrVkImageView*> fTextureViews;
184     SkTDArray<const GrVkResource*> fTextures;
185 
186     // GrVkResource used for TexelBuffers
187     SkTDArray<const GrVkBufferView*> fBufferViews;
188     SkTDArray<const GrVkResource*> fTexelBuffers;
189 
190     // Tracks the current render target uniforms stored in the vertex buffer.
191     RenderTargetState fRenderTargetState;
192     BuiltinUniformHandles fBuiltinUniformHandles;
193 
194     // Processors in the GrVkPipelineState
195     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
196     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
197     GrGLSLFragProcs fFragmentProcessors;
198 
199     Desc fDesc;
200 
201     GrVkPipelineStateDataManager fDataManager;
202 
203     int fNumSamplers;
204     int fNumTexelBuffers;
205 
206     friend class GrVkPipelineStateBuilder;
207 };
208 
209 #endif
210