GrVkProgram.cpp revision 164a9f061c5186ae931cc23a3c73f32472e80ff5
1164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/* 2164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel* Copyright 2016 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#include "GrVkProgram.h" 9164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h" 11164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkCommandBuffer.h" 12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkDescriptorPool.h" 13164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkGpu.h" 14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImageView.h" 15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkMemory.h" 16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkPipeline.h" 17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkSampler.h" 18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h" 19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkUniformBuffer.h" 20164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "glsl/GrGLSLFragmentProcessor.h" 21164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "glsl/GrGLSLGeometryProcessor.h" 22164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "glsl/GrGLSLXferProcessor.h" 23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkProgram::GrVkProgram(GrVkGpu* gpu, 25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkPipeline* pipeline, 26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineLayout layout, 27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDescriptorSetLayout dsLayout[2], 28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkDescriptorPool* descriptorPool, 29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDescriptorSet descriptorSets[2], 30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const BuiltinUniformHandles& builtinUniformHandles, 31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const UniformInfoArray& uniforms, 32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t vertexUniformSize, 33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t fragmentUniformSize, 34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t numSamplers, 35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGLSLPrimitiveProcessor* geometryProcessor, 36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGLSLXferProcessor* xferProcessor, 37164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrGLSLFragProcs& fragmentProcessors) 38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : fDescriptorPool(descriptorPool) 39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fPipeline(pipeline) 40164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fPipelineLayout(layout) 41164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fBuiltinUniformHandles(builtinUniformHandles) 42164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fGeometryProcessor(geometryProcessor) 43164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fXferProcessor(xferProcessor) 44164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fFragmentProcessors(fragmentProcessors) 45164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fProgramDataManager(uniforms, vertexUniformSize, fragmentUniformSize) { 46164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers.setReserve(numSamplers); 47164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews.setReserve(numSamplers); 48164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures.setReserve(numSamplers); 49164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 50164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(fDSLayout, dsLayout, 2 * sizeof(VkDescriptorSetLayout)); 51164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(fDescriptorSets, descriptorSets, 2 * sizeof(VkDescriptorSetLayout)); 52164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 53164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fVertexUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, vertexUniformSize, true)); 54164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize, true)); 55164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 56164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#ifdef SK_DEBUG 57164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fNumSamplers = numSamplers; 58164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 59164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 60164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 61164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkProgram::~GrVkProgram() { 62164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Must of freed all GPU resources before this is destroyed 63164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fPipeline); 64164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fDescriptorPool); 65164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fPipelineLayout); 66164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fDSLayout[0]); 67164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fDSLayout[1]); 68164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fSamplers.count()); 69164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fTextureViews.count()); 70164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!fTextures.count()); 71164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 72164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 73164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::freeTempResources(const GrVkGpu* gpu) { 74164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fSamplers.count(); ++i) { 75164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers[i]->unref(gpu); 76164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 77164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers.rewind(); 78164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 79164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextureViews.count(); ++i) { 80164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews[i]->unref(gpu); 81164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 82164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews.rewind(); 83164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 84164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextures.count(); ++i) { 85164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures[i]->unref(gpu); 86164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 87164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures.rewind(); 88164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 89164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::freeGPUResources(const GrVkGpu* gpu) { 91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fPipeline) { 92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipeline->unref(gpu); 93164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipeline = nullptr; 94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 95164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fDescriptorPool) { 96164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDescriptorPool->unref(gpu); 97164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDescriptorPool = nullptr; 98164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 99164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fPipelineLayout) { 100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), 101164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipelineLayout, 102164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr)); 103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipelineLayout = nullptr; 104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fDSLayout[0]) { 107164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[0], 108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr)); 109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDSLayout[0] = nullptr; 110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fDSLayout[1]) { 112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[1], 113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr)); 114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDSLayout[1] = nullptr; 115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVertexUniformBuffer) { 118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fVertexUniformBuffer->release(gpu); 119164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 120164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 121164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fFragmentUniformBuffer) { 122164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fFragmentUniformBuffer->release(gpu); 123164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 124164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->freeTempResources(gpu); 125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::abandonGPUResources() { 128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipeline->unrefAndAbandon(); 129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipeline = nullptr; 130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDescriptorPool->unrefAndAbandon(); 131164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDescriptorPool = nullptr; 132164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fPipelineLayout = nullptr; 133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDSLayout[0] = nullptr; 134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fDSLayout[1] = nullptr; 135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fVertexUniformBuffer->abandon(); 137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fFragmentUniformBuffer->abandon(); 138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fSamplers.count(); ++i) { 140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers[i]->unrefAndAbandon(); 141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers.rewind(); 143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextureViews.count(); ++i) { 145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews[i]->unrefAndAbandon(); 146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews.rewind(); 148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextures.count(); ++i) { 150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures[i]->unrefAndAbandon(); 151164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 152164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures.rewind(); 153164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 154164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic void append_texture_bindings(const GrProcessor& processor, 156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkTArray<const GrTextureAccess*>* textureBindings) { 157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (int numTextures = processor.numTextures()) { 158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures); 159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int i = 0; 160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel do { 161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bindings[i] = &processor.textureAccess(i); 162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } while (++i < numTextures); 163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::setData(const GrVkGpu* gpu, 167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrPrimitiveProcessor& primProc, 168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrPipeline& pipeline) { 169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This is here to protect against someone calling setData multiple times in a row without 170164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // freeing the tempData between calls. 171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->freeTempResources(gpu); 172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->setRenderTargetState(pipeline); 174164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 175164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkSTArray<8, const GrTextureAccess*> textureBindings; 176164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 177164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fGeometryProcessor->setData(fProgramDataManager, primProc); 178164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel append_texture_bindings(primProc, &textureBindings); 179164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 180164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fFragmentProcessors.count(); ++i) { 181164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i); 182164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fFragmentProcessors[i]->setData(fProgramDataManager, processor); 183164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fGeometryProcessor->setTransformData(primProc, fProgramDataManager, i, 184164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel processor.coordTransforms()); 185164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel append_texture_bindings(processor, &textureBindings); 186164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 187164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 188164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fXferProcessor->setData(fProgramDataManager, pipeline.getXferProcessor()); 189164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel append_texture_bindings(pipeline.getXferProcessor(), &textureBindings); 190164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 191164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->writeUniformBuffers(gpu); 192164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 193164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->writeSamplers(gpu, textureBindings); 194164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 195164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 196164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::writeUniformBuffers(const GrVkGpu* gpu) { 197164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fProgramDataManager.uploadUniformBuffers(gpu, fVertexUniformBuffer, fFragmentUniformBuffer); 198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 199164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkWriteDescriptorSet descriptorWrites[2]; 200164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(descriptorWrites, 0, 2 * sizeof(VkWriteDescriptorSet)); 201164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 202164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t firstUniformWrite = 0; 203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t uniformBindingUpdateCount = 0; 204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Vertex Uniform Buffer 206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVertexUniformBuffer.get()) { 207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ++uniformBindingUpdateCount; 208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDescriptorBufferInfo vertBufferInfo; 209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&vertBufferInfo, 0, sizeof(VkDescriptorBufferInfo)); 210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertBufferInfo.buffer = fVertexUniformBuffer->buffer(); 211164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertBufferInfo.offset = 0; 212164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertBufferInfo.range = fVertexUniformBuffer->size(); 213164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 214164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 215164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].pNext = nullptr; 216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].dstSet = fDescriptorSets[1]; 217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].dstBinding = GrVkUniformHandler::kVertexBinding; 218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].dstArrayElement = 0; 219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].descriptorCount = 1; 220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 221164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].pImageInfo = nullptr; 222164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].pBufferInfo = &vertBufferInfo; 223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[0].pTexelBufferView = nullptr; 224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Fragment Uniform Buffer 227164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fFragmentUniformBuffer.get()) { 228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (0 == uniformBindingUpdateCount) { 229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel firstUniformWrite = 1; 230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 231164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ++uniformBindingUpdateCount; 232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDescriptorBufferInfo fragBufferInfo; 233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&fragBufferInfo, 0, sizeof(VkDescriptorBufferInfo)); 234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fragBufferInfo.buffer = fFragmentUniformBuffer->buffer(); 235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fragBufferInfo.offset = 0; 236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fragBufferInfo.range = fFragmentUniformBuffer->size(); 237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].pNext = nullptr; 240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].dstSet = fDescriptorSets[1]; 241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].dstBinding = GrVkUniformHandler::kFragBinding;; 242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].dstArrayElement = 0; 243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].descriptorCount = 1; 244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].pImageInfo = nullptr; 246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].pBufferInfo = &fragBufferInfo; 247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel descriptorWrites[1].pTexelBufferView = nullptr; 248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (uniformBindingUpdateCount) { 251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uniformBindingUpdateCount, 253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &descriptorWrites[firstUniformWrite], 254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, nullptr)); 255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::writeSamplers(const GrVkGpu* gpu, 259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkTArray<const GrTextureAccess*>& textureBindings) { 260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fNumSamplers == textureBindings.count()); 261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < textureBindings.count(); ++i) { 263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fSamplers.push(GrVkSampler::Create(gpu, *textureBindings[i])); 264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture()); 266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkImage::Resource* textureResource = texture->resource(); 268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel textureResource->ref(); 269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextures.push(textureResource); 270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkImageView* textureView = texture->textureView(); 272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel textureView->ref(); 273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fTextureViews.push(textureView); 274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change texture layout so it can be read in shader 276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = texture->currentLayout(); 277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; 279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel texture->setImageLayout(gpu, 282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDescriptorImageInfo imageInfo; 290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo)); 291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageInfo.sampler = fSamplers[i]->sampler(); 292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageInfo.imageView = texture->textureView()->imageView(); 293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 295164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkWriteDescriptorSet writeInfo; 296164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet)); 297164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 298164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.pNext = nullptr; 299164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]; 300164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.dstBinding = i; 301164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.dstArrayElement = 0; 302164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.descriptorCount = 1; 303164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 304164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.pImageInfo = &imageInfo; 305164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.pBufferInfo = nullptr; 306164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel writeInfo.pTexelBufferView = nullptr; 307164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 308164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 310164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &writeInfo, 311164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, 312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr)); 313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 314164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 315164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::setRenderTargetState(const GrPipeline& pipeline) { 317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 318164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fBuiltinUniformHandles.fRTHeightUni.isValid() && 319164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) { 320164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, 321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkIntToScalar(pipeline.getRenderTarget()->height())); 322164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 323164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 324164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // set RT adjustment 325164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrRenderTarget* rt = pipeline.getRenderTarget(); 326164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkISize size; 327164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size.set(rt->width(), rt->height()); 328164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid()); 329164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fRenderTargetState.fRenderTargetOrigin != rt->origin() || 330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fRenderTargetState.fRenderTargetSize != size) { 331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fRenderTargetState.fRenderTargetSize = size; 332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fRenderTargetState.fRenderTargetOrigin = rt->origin(); 333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel float rtAdjustmentVec[4]; 335164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); 336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); 337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) { 341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer->bindPipeline(gpu, fPipeline); 342164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, 0, 2, fDescriptorSets, 0, 343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr); 344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 346164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkProgram::addUniformResources(GrVkCommandBuffer& commandBuffer) { 347164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#if 1 348164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fDescriptorPool); 349164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVertexUniformBuffer.get()) { 350164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fVertexUniformBuffer->resource()); 351164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 352164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fFragmentUniformBuffer.get()) { 353164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fFragmentUniformBuffer->resource()); 354164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 355164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fSamplers.count(); ++i) { 356164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fSamplers[i]); 357164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 358164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 359164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextureViews.count(); ++i) { 360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fTextureViews[i]); 361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int i = 0; i < fTextures.count(); ++i) { 364164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel commandBuffer.addResource(fTextures[i]); 365164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 368