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