Home | History | Annotate | Download | only in vk
      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 
     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 
     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                       std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
    104                       std::unique_ptr<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 
    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 float4 that adjusts the position from Skia device coords to Vulkans normalized device
    136         * coords. Assuming the transformed position, pos, is a homogeneous float3, 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
    155     void setRenderTargetState(const GrRenderTargetProxy*);
    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