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 "include/gpu/vk/GrVkTypes.h"
13 #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
14 #include "src/gpu/vk/GrVkDescriptorSetManager.h"
15 #include "src/gpu/vk/GrVkPipelineStateDataManager.h"
16 
17 class GrPipeline;
18 class GrStencilSettings;
19 class GrVkBufferView;
20 class GrVkCommandBuffer;
21 class GrVkDescriptorPool;
22 class GrVkDescriptorSet;
23 class GrVkGpu;
24 class GrVkImageView;
25 class GrVkPipeline;
26 class GrVkSampler;
27 class GrVkTexture;
28 class GrVkUniformBuffer;
29 
30 /**
31  * This class holds onto a GrVkPipeline object that we use for draws. Besides storing the acutal
32  * GrVkPipeline object, this class is also responsible handling all uniforms, descriptors, samplers,
33  * and other similar objects that are used along with the VkPipeline in the draw. This includes both
34  * allocating and freeing these objects, as well as updating their values.
35  */
36 class GrVkPipelineState : public SkRefCnt {
37 public:
38     using UniformInfoArray = GrVkPipelineStateDataManager::UniformInfoArray;
39     using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
40 
41     GrVkPipelineState(
42             GrVkGpu* gpu,
43             GrVkPipeline* pipeline,
44             const GrVkDescriptorSetManager::Handle& samplerDSHandle,
45             const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
46             const UniformInfoArray& uniforms,
47             uint32_t uniformSize,
48             const UniformInfoArray& samplers,
49             std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
50             std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
51             std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
52             int fFragmentProcessorCnt);
53 
54     ~GrVkPipelineState();
55 
56     void setAndBindUniforms(GrVkGpu*, const GrRenderTarget*, const GrProgramInfo&,
57                             GrVkCommandBuffer*);
58     /**
59      * This must be called after setAndBindUniforms() since that function invalidates texture
60      * bindings.
61      */
62     void setAndBindTextures(GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&,
63                             const GrTextureProxy* const primitiveProcessorTextures[],
64                             GrVkCommandBuffer*);
65 
66     void bindPipeline(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
67 
68     void addUniformResources(GrVkCommandBuffer&, GrVkSampler*[], GrVkTexture*[], int numTextures);
69 
70     void freeGPUResources(GrVkGpu* gpu);
71 
72     void abandonGPUResources();
73 
74 private:
75     void writeUniformBuffers(const GrVkGpu* gpu);
76 
77     /**
78      * We use the RT's size and origin to adjust from Skia device space to vulkan normalized device
79      * space and to make device space positions have the correct origin for processors that require
80      * them.
81      */
82     struct RenderTargetState {
83         SkISize         fRenderTargetSize;
84         GrSurfaceOrigin fRenderTargetOrigin;
85 
RenderTargetStateRenderTargetState86         RenderTargetState() { this->invalidate(); }
invalidateRenderTargetState87         void invalidate() {
88             fRenderTargetSize.fWidth = -1;
89             fRenderTargetSize.fHeight = -1;
90             fRenderTargetOrigin = (GrSurfaceOrigin)-1;
91         }
92 
93         /**
94         * Gets a float4 that adjusts the position from Skia device coords to Vulkans normalized device
95         * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is
96         * applied as such:
97         * pos.x = dot(v.xy, pos.xz)
98         * pos.y = dot(v.zw, pos.yz)
99         */
getRTAdjustmentVecRenderTargetState100         void getRTAdjustmentVec(float* destVec) {
101             destVec[0] = 2.f / fRenderTargetSize.fWidth;
102             destVec[1] = -1.f;
103             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
104                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
105                 destVec[3] = 1.f;
106             } else {
107                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
108                 destVec[3] = -1.f;
109             }
110         }
111     };
112 
113     // Helper for setData() that sets the view matrix and loads the render target height uniform
114     void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
115 
116     // GrVkResources
117     GrVkPipeline* fPipeline;
118 
119     // The DescriptorSets need to survive until the gpu has finished all draws that use them.
120     // However, they will only be freed by the descriptor pool. Thus by simply keeping the
121     // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do
122     // not need a GrVkResource versions of VkDescriptorSet. We hold on to these in the
123     // GrVkPipelineState since we update the descriptor sets and bind them at separate times;
124     VkDescriptorSet fDescriptorSets[3];
125 
126     const GrVkDescriptorSet* fUniformDescriptorSet;
127     const GrVkDescriptorSet* fSamplerDescriptorSet;
128 
129     const GrVkDescriptorSetManager::Handle fSamplerDSHandle;
130 
131     SkSTArray<4, const GrVkSampler*>   fImmutableSamplers;
132 
133     std::unique_ptr<GrVkUniformBuffer> fUniformBuffer;
134 
135     // Tracks the current render target uniforms stored in the vertex buffer.
136     RenderTargetState fRenderTargetState;
137     GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
138 
139     // Processors in the GrVkPipelineState
140     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
141     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
142     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
143     int fFragmentProcessorCnt;
144 
145     GrVkPipelineStateDataManager fDataManager;
146 
147     int fNumSamplers;
148 };
149 
150 #endif
151