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