blob: 190ad06e48305969ef7db284acca74efe1eaf9b6 [file] [log] [blame]
egdaniel22281c12016-03-23 13:49:40 -07001/*
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
egdaniel5d8f69f2016-09-07 07:24:12 -070012#include "GrProgramDesc.h"
cdalton93a379b2016-05-11 13:58:08 -070013#include "GrStencilSettings.h"
egdaniel707bbd62016-07-26 07:19:47 -070014#include "GrVkDescriptorSetManager.h"
egdaniel22281c12016-03-23 13:49:40 -070015#include "GrVkImage.h"
egdaniel22281c12016-03-23 13:49:40 -070016#include "GrVkPipelineStateDataManager.h"
17#include "glsl/GrGLSLProgramBuilder.h"
18
jvanverthe50f3e72016-03-28 07:03:06 -070019#include "vk/GrVkDefines.h"
egdaniel22281c12016-03-23 13:49:40 -070020
21class GrPipeline;
Greg Daniel31ec1442017-05-08 10:30:59 -040022class GrVkBufferView;
egdaniel22281c12016-03-23 13:49:40 -070023class GrVkCommandBuffer;
24class GrVkDescriptorPool;
egdaniela95220d2016-07-21 11:50:37 -070025class GrVkDescriptorSet;
egdaniel22281c12016-03-23 13:49:40 -070026class GrVkGpu;
27class GrVkImageView;
28class GrVkPipeline;
29class GrVkSampler;
30class 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 */
38class GrVkPipelineState : public SkRefCnt {
39public:
40 typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
41
42 ~GrVkPipelineState();
43
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
egdaniel22281c12016-03-23 13:49:40 -070060 /**
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 *
egdaniel720dc712016-09-07 11:56:59 -070064 * The GrProgramDesc contains all the information need to create the actual shaders for the
egdaniel22281c12016-03-23 13:49:40 -070065 * pipeline.
66 *
egdaniel720dc712016-09-07 11:56:59 -070067 * 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
egdaniel22281c12016-03-23 13:49:40 -070069 * 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.
egdaniel22281c12016-03-23 13:49:40 -070072 */
egdaniel720dc712016-09-07 11:56:59 -070073 class Desc : public GrProgramDesc {
74 public:
75 static bool Build(Desc*,
76 const GrPrimitiveProcessor&,
77 const GrPipeline&,
csmartdaltonc633abb2016-11-01 08:55:55 -070078 const GrStencilSettings&,
egdaniel720dc712016-09-07 11:56:59 -070079 GrPrimitiveType primitiveType,
Brian Salomon94efbf52016-11-29 13:43:05 -050080 const GrShaderCaps&);
egdaniel720dc712016-09-07 11:56:59 -070081 private:
82 typedef GrProgramDesc INHERITED;
egdaniel22281c12016-03-23 13:49:40 -070083 };
84
85 const Desc& getDesc() { return fDesc; }
86
87private:
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,
egdaniel707bbd62016-07-26 07:19:47 -070095 const GrVkDescriptorSetManager::Handle& samplerDSHandle,
Greg Daniel31ec1442017-05-08 10:30:59 -040096 const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
egdaniel22281c12016-03-23 13:49:40 -070097 const BuiltinUniformHandles& builtinUniformHandles,
98 const UniformInfoArray& uniforms,
Greg Daniel18f96022017-05-04 15:09:03 -040099 uint32_t geometryUniformSize,
egdaniel22281c12016-03-23 13:49:40 -0700100 uint32_t fragmentUniformSize,
101 uint32_t numSamplers,
Greg Daniel31ec1442017-05-08 10:30:59 -0400102 uint32_t numTexelBuffers,
egdaniel22281c12016-03-23 13:49:40 -0700103 GrGLSLPrimitiveProcessor* geometryProcessor,
104 GrGLSLXferProcessor* xferProcessor,
105 const GrGLSLFragProcs& fragmentProcessors);
106
egdaniel22281c12016-03-23 13:49:40 -0700107 void writeUniformBuffers(const GrVkGpu* gpu);
108
Brian Salomonab015ef2017-04-04 10:15:51 -0400109 void writeSamplers(
110 GrVkGpu* gpu,
111 const SkTArray<const GrResourceIOProcessor::TextureSampler*>& textureBindings,
112 bool allowSRGBInputs);
egdaniel22281c12016-03-23 13:49:40 -0700113
Greg Daniel31ec1442017-05-08 10:30:59 -0400114 void writeTexelBuffers(
115 GrVkGpu* gpu,
116 const SkTArray<const GrResourceIOProcessor::BufferAccess*>& bufferAccesses);
117
egdaniel22281c12016-03-23 13:49:40 -0700118 /**
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
127 RenderTargetState() { this->invalidate(); }
128 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 */
141 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
Robert Phillips02bb6df2017-03-28 17:11:19 -0400155 void setRenderTargetState(const GrRenderTarget*);
egdaniel22281c12016-03-23 13:49:40 -0700156
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;
Greg Daniel31ec1442017-05-08 10:30:59 -0400169 VkDescriptorSet fDescriptorSets[3];
egdaniel22281c12016-03-23 13:49:40 -0700170
egdaniela95220d2016-07-21 11:50:37 -0700171 const GrVkDescriptorSet* fUniformDescriptorSet;
egdaniel707bbd62016-07-26 07:19:47 -0700172 const GrVkDescriptorSet* fSamplerDescriptorSet;
Greg Daniel31ec1442017-05-08 10:30:59 -0400173 const GrVkDescriptorSet* fTexelBufferDescriptorSet;
egdaniel707bbd62016-07-26 07:19:47 -0700174
175 const GrVkDescriptorSetManager::Handle fSamplerDSHandle;
Greg Daniel31ec1442017-05-08 10:30:59 -0400176 const GrVkDescriptorSetManager::Handle fTexelBufferDSHandle;
egdaniel22281c12016-03-23 13:49:40 -0700177
Greg Daniel18f96022017-05-04 15:09:03 -0400178 std::unique_ptr<GrVkUniformBuffer> fGeometryUniformBuffer;
Ben Wagner145dbcd2016-11-03 14:40:50 -0400179 std::unique_ptr<GrVkUniformBuffer> fFragmentUniformBuffer;
egdaniel22281c12016-03-23 13:49:40 -0700180
181 // GrVkResources used for sampling textures
182 SkTDArray<GrVkSampler*> fSamplers;
183 SkTDArray<const GrVkImageView*> fTextureViews;
egdanielb2df0c22016-05-13 11:30:37 -0700184 SkTDArray<const GrVkResource*> fTextures;
egdaniel22281c12016-03-23 13:49:40 -0700185
Greg Daniel31ec1442017-05-08 10:30:59 -0400186 // GrVkResource used for TexelBuffers
187 SkTDArray<const GrVkBufferView*> fBufferViews;
188 SkTDArray<const GrVkResource*> fTexelBuffers;
189
egdaniel22281c12016-03-23 13:49:40 -0700190 // Tracks the current render target uniforms stored in the vertex buffer.
191 RenderTargetState fRenderTargetState;
192 BuiltinUniformHandles fBuiltinUniformHandles;
193
194 // Processors in the GrVkPipelineState
Ben Wagner145dbcd2016-11-03 14:40:50 -0400195 std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
196 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
egdaniel22281c12016-03-23 13:49:40 -0700197 GrGLSLFragProcs fFragmentProcessors;
198
199 Desc fDesc;
200
201 GrVkPipelineStateDataManager fDataManager;
202
egdaniel22281c12016-03-23 13:49:40 -0700203 int fNumSamplers;
Greg Daniel31ec1442017-05-08 10:30:59 -0400204 int fNumTexelBuffers;
egdaniel22281c12016-03-23 13:49:40 -0700205
206 friend class GrVkPipelineStateBuilder;
207};
208
209#endif