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*, GrSurfaceOrigin, 57 const GrPrimitiveProcessor&, const GrPipeline&, 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