1164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/*
2164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Copyright 2015 Google Inc.
3164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel *
4164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Use of this source code is governed by a BSD-style license that can be
5164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * found in the LICENSE file.
6164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel */
7164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#ifndef GrVkProgram_DEFINED
10164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define GrVkProgram_DEFINED
11164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImage.h"
13164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkProgramDesc.h"
14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkProgramDataManager.h"
15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "glsl/GrGLSLProgramBuilder.h"
16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vulkan/vulkan.h"
18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrPipeline;
20164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkCommandBuffer;
21164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkDescriptorPool;
22164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkGpu;
23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkImageView;
24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkPipeline;
25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkSampler;
26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkUniformBuffer;
27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielclass GrVkProgram : public SkRefCnt {
29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielpublic:
30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    ~GrVkProgram();
33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkPipeline* vkPipeline() const { return fPipeline; }
35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void setData(const GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&);
37164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
40164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void addUniformResources(GrVkCommandBuffer&);
41164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
42164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void freeGPUResources(const GrVkGpu* gpu);
43164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
44164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // This releases resources the only a given instance of a GrVkProgram needs to hold onto and do
45164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // don't need to survive across new uses of the program.
46164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void freeTempResources(const GrVkGpu* gpu);
47164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
48164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void abandonGPUResources();
49164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
50164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielprivate:
51164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    typedef GrVkProgramDataManager::UniformInfoArray UniformInfoArray;
52164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
53164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
54164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkProgram(GrVkGpu* gpu,
55164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                GrVkPipeline* pipeline,
56164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                VkPipelineLayout layout,
57164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                VkDescriptorSetLayout dsLayout[2],
58164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                GrVkDescriptorPool* descriptorPool,
59164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                VkDescriptorSet descriptorSets[2],
60164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                const BuiltinUniformHandles& builtinUniformHandles,
61164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                const UniformInfoArray& uniforms,
62164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                uint32_t vertexUniformSize,
63164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                uint32_t fragmentUniformSize,
64164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                uint32_t numSamplers,
65164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                GrGLSLPrimitiveProcessor* geometryProcessor,
66164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                GrGLSLXferProcessor* xferProcessor,
67164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                const GrGLSLFragProcs& fragmentProcessors);
68164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
69164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void writeUniformBuffers(const GrVkGpu* gpu);
70164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
71164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void writeSamplers(const GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings);
72164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
73164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
74164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    /**
75164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    * We use the RT's size and origin to adjust from Skia device space to OpenGL normalized device
76164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    * space and to make device space positions have the correct origin for processors that require
77164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    * them.
78164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    */
79164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    struct RenderTargetState {
80164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        SkISize         fRenderTargetSize;
81164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        GrSurfaceOrigin fRenderTargetOrigin;
82164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
83164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        RenderTargetState() { this->invalidate(); }
84164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        void invalidate() {
85164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            fRenderTargetSize.fWidth = -1;
86164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            fRenderTargetSize.fHeight = -1;
87164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            fRenderTargetOrigin = (GrSurfaceOrigin)-1;
88164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
89164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        /**
91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device
92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
93164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        * applied as such:
94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        * pos.x = dot(v.xy, pos.xz)
95164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        * pos.y = dot(v.zw, pos.yz)
96164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        */
97164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        void getRTAdjustmentVec(float* destVec) {
98164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            destVec[0] = 2.f / fRenderTargetSize.fWidth;
99164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            destVec[1] = -1.f;
100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
101164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                destVec[2] = -2.f / fRenderTargetSize.fHeight;
102164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                destVec[3] = 1.f;
103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            } else {
104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                destVec[2] = 2.f / fRenderTargetSize.fHeight;
105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                destVec[3] = -1.f;
106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            }
107164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    };
109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Helper for setData() that sets the view matrix and loads the render target height uniform
111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void setRenderTargetState(const GrPipeline&);
112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//    GrVkGpu* fGpu;
114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // GrVkResources
116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkDescriptorPool* fDescriptorPool;
117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkPipeline*       fPipeline;
118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
119164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Used for binding DescriptorSets to the command buffer but does not need to survive during
120164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // command buffer execution. Thus this is not need to be a GrVkResource.
121164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkPipelineLayout fPipelineLayout;
122164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
123164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // The first set (index 0) will be used for samplers and the second set (index 1) will be
124164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // used for uniform buffers.
125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // The DSLayouts only are needed for allocating the descriptor sets and must survive until after
126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // descriptor sets have been updated. Thus the lifetime of the layouts will just be the life of
127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    //the GrVkProgram.
128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkDescriptorSetLayout fDSLayout[2];
129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // The DescriptorSets need to survive until the gpu has finished all draws that use them.
130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // However, they will only be freed by the descriptor pool. Thus by simply keeping the
131164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do
132164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // not need a GrVkResource versions of VkDescriptorSet.
133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkDescriptorSet       fDescriptorSets[2];
134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkAutoTDelete<GrVkUniformBuffer>    fVertexUniformBuffer;
136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkAutoTDelete<GrVkUniformBuffer>    fFragmentUniformBuffer;
137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // GrVkResources used for sampling textures
139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkTDArray<GrVkSampler*>                fSamplers;
140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkTDArray<const GrVkImageView*>        fTextureViews;
141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkTDArray<const GrVkImage::Resource*>  fTextures;
142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Tracks the current render target uniforms stored in the vertex buffer.
144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    RenderTargetState fRenderTargetState;
145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    BuiltinUniformHandles fBuiltinUniformHandles;
146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Processors in the program
148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkAutoTDelete<GrGLSLPrimitiveProcessor> fGeometryProcessor;
149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkAutoTDelete<GrGLSLXferProcessor> fXferProcessor;
150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrGLSLFragProcs fFragmentProcessors;
151164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
152164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkProgramDataManager fProgramDataManager;
153164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
154164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#ifdef SK_DEBUG
155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int fNumSamplers;
156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif
157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    friend class GrVkProgramBuilder;
159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel};
160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif
162