1 /* 2 * Copyright 2015 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 GrVkProgram_DEFINED 10 #define GrVkProgram_DEFINED 11 12 #include "GrVkImage.h" 13 #include "GrVkProgramDesc.h" 14 #include "GrVkProgramDataManager.h" 15 #include "glsl/GrGLSLProgramBuilder.h" 16 17 #include "vulkan/vulkan.h" 18 19 class GrPipeline; 20 class GrVkCommandBuffer; 21 class GrVkDescriptorPool; 22 class GrVkGpu; 23 class GrVkImageView; 24 class GrVkPipeline; 25 class GrVkSampler; 26 class GrVkUniformBuffer; 27 28 class GrVkProgram : public SkRefCnt { 29 public: 30 typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles; 31 32 ~GrVkProgram(); 33 vkPipeline()34 GrVkPipeline* vkPipeline() const { return fPipeline; } 35 36 void setData(const GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&); 37 38 void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer); 39 40 void addUniformResources(GrVkCommandBuffer&); 41 42 void freeGPUResources(const GrVkGpu* gpu); 43 44 // This releases resources the only a given instance of a GrVkProgram needs to hold onto and do 45 // don't need to survive across new uses of the program. 46 void freeTempResources(const GrVkGpu* gpu); 47 48 void abandonGPUResources(); 49 50 private: 51 typedef GrVkProgramDataManager::UniformInfoArray UniformInfoArray; 52 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; 53 54 GrVkProgram(GrVkGpu* gpu, 55 GrVkPipeline* pipeline, 56 VkPipelineLayout layout, 57 VkDescriptorSetLayout dsLayout[2], 58 GrVkDescriptorPool* descriptorPool, 59 VkDescriptorSet descriptorSets[2], 60 const BuiltinUniformHandles& builtinUniformHandles, 61 const UniformInfoArray& uniforms, 62 uint32_t vertexUniformSize, 63 uint32_t fragmentUniformSize, 64 uint32_t numSamplers, 65 GrGLSLPrimitiveProcessor* geometryProcessor, 66 GrGLSLXferProcessor* xferProcessor, 67 const GrGLSLFragProcs& fragmentProcessors); 68 69 void writeUniformBuffers(const GrVkGpu* gpu); 70 71 void writeSamplers(const GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings); 72 73 74 /** 75 * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device 76 * space and to make device space positions have the correct origin for processors that require 77 * them. 78 */ 79 struct RenderTargetState { 80 SkISize fRenderTargetSize; 81 GrSurfaceOrigin fRenderTargetOrigin; 82 RenderTargetStateRenderTargetState83 RenderTargetState() { this->invalidate(); } invalidateRenderTargetState84 void invalidate() { 85 fRenderTargetSize.fWidth = -1; 86 fRenderTargetSize.fHeight = -1; 87 fRenderTargetOrigin = (GrSurfaceOrigin)-1; 88 } 89 90 /** 91 * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device 92 * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is 93 * applied as such: 94 * pos.x = dot(v.xy, pos.xz) 95 * pos.y = dot(v.zw, pos.yz) 96 */ getRTAdjustmentVecRenderTargetState97 void getRTAdjustmentVec(float* destVec) { 98 destVec[0] = 2.f / fRenderTargetSize.fWidth; 99 destVec[1] = -1.f; 100 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 101 destVec[2] = -2.f / fRenderTargetSize.fHeight; 102 destVec[3] = 1.f; 103 } else { 104 destVec[2] = 2.f / fRenderTargetSize.fHeight; 105 destVec[3] = -1.f; 106 } 107 } 108 }; 109 110 // Helper for setData() that sets the view matrix and loads the render target height uniform 111 void setRenderTargetState(const GrPipeline&); 112 113 // GrVkGpu* fGpu; 114 115 // GrVkResources 116 GrVkDescriptorPool* fDescriptorPool; 117 GrVkPipeline* fPipeline; 118 119 // Used for binding DescriptorSets to the command buffer but does not need to survive during 120 // command buffer execution. Thus this is not need to be a GrVkResource. 121 VkPipelineLayout fPipelineLayout; 122 123 // The first set (index 0) will be used for samplers and the second set (index 1) will be 124 // used for uniform buffers. 125 // The DSLayouts only are needed for allocating the descriptor sets and must survive until after 126 // descriptor sets have been updated. Thus the lifetime of the layouts will just be the life of 127 //the GrVkProgram. 128 VkDescriptorSetLayout fDSLayout[2]; 129 // The DescriptorSets need to survive until the gpu has finished all draws that use them. 130 // However, they will only be freed by the descriptor pool. Thus by simply keeping the 131 // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do 132 // not need a GrVkResource versions of VkDescriptorSet. 133 VkDescriptorSet fDescriptorSets[2]; 134 135 SkAutoTDelete<GrVkUniformBuffer> fVertexUniformBuffer; 136 SkAutoTDelete<GrVkUniformBuffer> fFragmentUniformBuffer; 137 138 // GrVkResources used for sampling textures 139 SkTDArray<GrVkSampler*> fSamplers; 140 SkTDArray<const GrVkImageView*> fTextureViews; 141 SkTDArray<const GrVkImage::Resource*> fTextures; 142 143 // Tracks the current render target uniforms stored in the vertex buffer. 144 RenderTargetState fRenderTargetState; 145 BuiltinUniformHandles fBuiltinUniformHandles; 146 147 // Processors in the program 148 SkAutoTDelete<GrGLSLPrimitiveProcessor> fGeometryProcessor; 149 SkAutoTDelete<GrGLSLXferProcessor> fXferProcessor; 150 GrGLSLFragProcs fFragmentProcessors; 151 152 GrVkProgramDataManager fProgramDataManager; 153 154 #ifdef SK_DEBUG 155 int fNumSamplers; 156 #endif 157 158 friend class GrVkProgramBuilder; 159 }; 160 161 #endif 162