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