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 #include "GrVkPipelineState.h" 9 10 #include "GrPipeline.h" 11 #include "GrTexturePriv.h" 12 #include "GrVkCommandBuffer.h" 13 #include "GrVkDescriptorPool.h" 14 #include "GrVkDescriptorSet.h" 15 #include "GrVkGpu.h" 16 #include "GrVkImageView.h" 17 #include "GrVkMemory.h" 18 #include "GrVkPipeline.h" 19 #include "GrVkRenderTarget.h" 20 #include "GrVkSampler.h" 21 #include "GrVkTexture.h" 22 #include "GrVkUniformBuffer.h" 23 #include "glsl/GrGLSLFragmentProcessor.h" 24 #include "glsl/GrGLSLGeometryProcessor.h" 25 #include "glsl/GrGLSLXferProcessor.h" 26 #include "SkMipMap.h" 27 28 GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu, 29 const GrVkPipelineState::Desc& desc, 30 GrVkPipeline* pipeline, 31 VkPipelineLayout layout, 32 const GrVkDescriptorSetManager::Handle& samplerDSHandle, 33 const BuiltinUniformHandles& builtinUniformHandles, 34 const UniformInfoArray& uniforms, 35 uint32_t vertexUniformSize, 36 uint32_t fragmentUniformSize, 37 uint32_t numSamplers, 38 GrGLSLPrimitiveProcessor* geometryProcessor, 39 GrGLSLXferProcessor* xferProcessor, 40 const GrGLSLFragProcs& fragmentProcessors) 41 : fPipeline(pipeline) 42 , fPipelineLayout(layout) 43 , fUniformDescriptorSet(nullptr) 44 , fSamplerDescriptorSet(nullptr) 45 , fSamplerDSHandle(samplerDSHandle) 46 , fStartDS(SK_MaxS32) 47 , fDSCount(0) 48 , fBuiltinUniformHandles(builtinUniformHandles) 49 , fGeometryProcessor(geometryProcessor) 50 , fXferProcessor(xferProcessor) 51 , fFragmentProcessors(fragmentProcessors) 52 , fDesc(desc) 53 , fDataManager(uniforms, vertexUniformSize, fragmentUniformSize) { 54 fSamplers.setReserve(numSamplers); 55 fTextureViews.setReserve(numSamplers); 56 fTextures.setReserve(numSamplers); 57 58 fDescriptorSets[0] = VK_NULL_HANDLE; 59 fDescriptorSets[1] = VK_NULL_HANDLE; 60 61 // Currently we are always binding a descriptor set for uniform buffers. 62 if (vertexUniformSize || fragmentUniformSize) { 63 fDSCount++; 64 fStartDS = GrVkUniformHandler::kUniformBufferDescSet; 65 } 66 if (numSamplers) { 67 fDSCount++; 68 fStartDS = SkTMin(fStartDS, (int)GrVkUniformHandler::kSamplerDescSet); 69 } 70 71 fVertexUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, vertexUniformSize)); 72 fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize)); 73 74 fNumSamplers = numSamplers; 75 } 76 77 GrVkPipelineState::~GrVkPipelineState() { 78 // Must have freed all GPU resources before this is destroyed 79 SkASSERT(!fPipeline); 80 SkASSERT(!fPipelineLayout); 81 SkASSERT(!fSamplers.count()); 82 SkASSERT(!fTextureViews.count()); 83 SkASSERT(!fTextures.count()); 84 for (int i = 0; i < fFragmentProcessors.count(); ++i) { 85 delete fFragmentProcessors[i]; 86 } 87 } 88 89 void GrVkPipelineState::freeTempResources(const GrVkGpu* gpu) { 90 for (int i = 0; i < fSamplers.count(); ++i) { 91 fSamplers[i]->unref(gpu); 92 } 93 fSamplers.rewind(); 94 95 for (int i = 0; i < fTextureViews.count(); ++i) { 96 fTextureViews[i]->unref(gpu); 97 } 98 fTextureViews.rewind(); 99 100 for (int i = 0; i < fTextures.count(); ++i) { 101 fTextures[i]->unref(gpu); 102 } 103 fTextures.rewind(); 104 } 105 106 void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) { 107 if (fPipeline) { 108 fPipeline->unref(gpu); 109 fPipeline = nullptr; 110 } 111 112 if (fPipelineLayout) { 113 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), 114 fPipelineLayout, 115 nullptr)); 116 fPipelineLayout = VK_NULL_HANDLE; 117 } 118 119 if (fVertexUniformBuffer) { 120 fVertexUniformBuffer->release(gpu); 121 } 122 123 if (fFragmentUniformBuffer) { 124 fFragmentUniformBuffer->release(gpu); 125 } 126 127 if (fUniformDescriptorSet) { 128 fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu)); 129 fUniformDescriptorSet = nullptr; 130 } 131 132 if (fSamplerDescriptorSet) { 133 fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu)); 134 fSamplerDescriptorSet = nullptr; 135 } 136 137 this->freeTempResources(gpu); 138 } 139 140 void GrVkPipelineState::abandonGPUResources() { 141 fPipeline->unrefAndAbandon(); 142 fPipeline = nullptr; 143 144 fPipelineLayout = VK_NULL_HANDLE; 145 146 fVertexUniformBuffer->abandon(); 147 fFragmentUniformBuffer->abandon(); 148 149 for (int i = 0; i < fSamplers.count(); ++i) { 150 fSamplers[i]->unrefAndAbandon(); 151 } 152 fSamplers.rewind(); 153 154 for (int i = 0; i < fTextureViews.count(); ++i) { 155 fTextureViews[i]->unrefAndAbandon(); 156 } 157 fTextureViews.rewind(); 158 159 for (int i = 0; i < fTextures.count(); ++i) { 160 fTextures[i]->unrefAndAbandon(); 161 } 162 fTextures.rewind(); 163 164 if (fUniformDescriptorSet) { 165 fUniformDescriptorSet->unrefAndAbandon(); 166 fUniformDescriptorSet = nullptr; 167 } 168 169 if (fSamplerDescriptorSet) { 170 fSamplerDescriptorSet->unrefAndAbandon(); 171 fSamplerDescriptorSet = nullptr; 172 } 173 } 174 175 static void append_texture_bindings(const GrProcessor& processor, 176 SkTArray<const GrProcessor::TextureSampler*>* textureBindings) { 177 // We don't support image storages in VK. 178 SkASSERT(!processor.numImageStorages()); 179 if (int numTextureSamplers = processor.numTextureSamplers()) { 180 const GrProcessor::TextureSampler** bindings = 181 textureBindings->push_back_n(numTextureSamplers); 182 int i = 0; 183 do { 184 bindings[i] = &processor.textureSampler(i); 185 } while (++i < numTextureSamplers); 186 } 187 } 188 189 void GrVkPipelineState::setData(GrVkGpu* gpu, 190 const GrPrimitiveProcessor& primProc, 191 const GrPipeline& pipeline) { 192 // This is here to protect against someone calling setData multiple times in a row without 193 // freeing the tempData between calls. 194 this->freeTempResources(gpu); 195 196 this->setRenderTargetState(pipeline); 197 198 SkSTArray<8, const GrProcessor::TextureSampler*> textureBindings; 199 200 fGeometryProcessor->setData(fDataManager, primProc, 201 GrFragmentProcessor::CoordTransformIter(pipeline)); 202 append_texture_bindings(primProc, &textureBindings); 203 204 GrFragmentProcessor::Iter iter(pipeline); 205 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(), 206 fFragmentProcessors.count()); 207 const GrFragmentProcessor* fp = iter.next(); 208 GrGLSLFragmentProcessor* glslFP = glslIter.next(); 209 while (fp && glslFP) { 210 glslFP->setData(fDataManager, *fp); 211 append_texture_bindings(*fp, &textureBindings); 212 fp = iter.next(); 213 glslFP = glslIter.next(); 214 } 215 SkASSERT(!fp && !glslFP); 216 217 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor()); 218 append_texture_bindings(pipeline.getXferProcessor(), &textureBindings); 219 220 // Get new descriptor sets 221 if (fNumSamplers) { 222 if (fSamplerDescriptorSet) { 223 fSamplerDescriptorSet->recycle(gpu); 224 } 225 fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle); 226 int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet; 227 fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet(); 228 this->writeSamplers(gpu, textureBindings, pipeline.getAllowSRGBInputs()); 229 } 230 231 if (fVertexUniformBuffer.get() || fFragmentUniformBuffer.get()) { 232 if (fDataManager.uploadUniformBuffers(gpu, 233 fVertexUniformBuffer.get(), 234 fFragmentUniformBuffer.get()) 235 || !fUniformDescriptorSet) 236 { 237 if (fUniformDescriptorSet) { 238 fUniformDescriptorSet->recycle(gpu); 239 } 240 fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet(); 241 int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet; 242 fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet(); 243 this->writeUniformBuffers(gpu); 244 } 245 } 246 } 247 248 void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) { 249 VkWriteDescriptorSet descriptorWrites[2]; 250 memset(descriptorWrites, 0, 2 * sizeof(VkWriteDescriptorSet)); 251 252 uint32_t firstUniformWrite = 0; 253 uint32_t uniformBindingUpdateCount = 0; 254 255 VkDescriptorBufferInfo vertBufferInfo; 256 // Vertex Uniform Buffer 257 if (fVertexUniformBuffer.get()) { 258 ++uniformBindingUpdateCount; 259 memset(&vertBufferInfo, 0, sizeof(VkDescriptorBufferInfo)); 260 vertBufferInfo.buffer = fVertexUniformBuffer->buffer(); 261 vertBufferInfo.offset = fVertexUniformBuffer->offset(); 262 vertBufferInfo.range = fVertexUniformBuffer->size(); 263 264 descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 265 descriptorWrites[0].pNext = nullptr; 266 descriptorWrites[0].dstSet = fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]; 267 descriptorWrites[0].dstBinding = GrVkUniformHandler::kVertexBinding; 268 descriptorWrites[0].dstArrayElement = 0; 269 descriptorWrites[0].descriptorCount = 1; 270 descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 271 descriptorWrites[0].pImageInfo = nullptr; 272 descriptorWrites[0].pBufferInfo = &vertBufferInfo; 273 descriptorWrites[0].pTexelBufferView = nullptr; 274 } 275 276 VkDescriptorBufferInfo fragBufferInfo; 277 // Fragment Uniform Buffer 278 if (fFragmentUniformBuffer.get()) { 279 if (0 == uniformBindingUpdateCount) { 280 firstUniformWrite = 1; 281 } 282 ++uniformBindingUpdateCount; 283 memset(&fragBufferInfo, 0, sizeof(VkDescriptorBufferInfo)); 284 fragBufferInfo.buffer = fFragmentUniformBuffer->buffer(); 285 fragBufferInfo.offset = fFragmentUniformBuffer->offset(); 286 fragBufferInfo.range = fFragmentUniformBuffer->size(); 287 288 descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 289 descriptorWrites[1].pNext = nullptr; 290 descriptorWrites[1].dstSet = fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]; 291 descriptorWrites[1].dstBinding = GrVkUniformHandler::kFragBinding;; 292 descriptorWrites[1].dstArrayElement = 0; 293 descriptorWrites[1].descriptorCount = 1; 294 descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 295 descriptorWrites[1].pImageInfo = nullptr; 296 descriptorWrites[1].pBufferInfo = &fragBufferInfo; 297 descriptorWrites[1].pTexelBufferView = nullptr; 298 } 299 300 if (uniformBindingUpdateCount) { 301 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 302 uniformBindingUpdateCount, 303 &descriptorWrites[firstUniformWrite], 304 0, nullptr)); 305 } 306 } 307 308 void GrVkPipelineState::writeSamplers( 309 GrVkGpu* gpu, 310 const SkTArray<const GrProcessor::TextureSampler*>& textureBindings, 311 bool allowSRGBInputs) { 312 SkASSERT(fNumSamplers == textureBindings.count()); 313 314 for (int i = 0; i < textureBindings.count(); ++i) { 315 const GrSamplerParams& params = textureBindings[i]->params(); 316 317 GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->texture()); 318 319 fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(params, 320 texture->texturePriv().maxMipMapLevel())); 321 322 const GrVkResource* textureResource = texture->resource(); 323 textureResource->ref(); 324 fTextures.push(textureResource); 325 326 const GrVkImageView* textureView = texture->textureView(allowSRGBInputs); 327 textureView->ref(); 328 fTextureViews.push(textureView); 329 330 VkDescriptorImageInfo imageInfo; 331 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo)); 332 imageInfo.sampler = fSamplers[i]->sampler(); 333 imageInfo.imageView = textureView->imageView(); 334 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 335 336 VkWriteDescriptorSet writeInfo; 337 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet)); 338 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 339 writeInfo.pNext = nullptr; 340 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]; 341 writeInfo.dstBinding = i; 342 writeInfo.dstArrayElement = 0; 343 writeInfo.descriptorCount = 1; 344 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 345 writeInfo.pImageInfo = &imageInfo; 346 writeInfo.pBufferInfo = nullptr; 347 writeInfo.pTexelBufferView = nullptr; 348 349 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 350 1, 351 &writeInfo, 352 0, 353 nullptr)); 354 } 355 } 356 357 void GrVkPipelineState::setRenderTargetState(const GrPipeline& pipeline) { 358 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 359 if (fBuiltinUniformHandles.fRTHeightUni.isValid() && 360 fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) { 361 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, 362 SkIntToScalar(pipeline.getRenderTarget()->height())); 363 } 364 365 // set RT adjustment 366 const GrRenderTarget* rt = pipeline.getRenderTarget(); 367 SkISize size; 368 size.set(rt->width(), rt->height()); 369 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid()); 370 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() || 371 fRenderTargetState.fRenderTargetSize != size) { 372 fRenderTargetState.fRenderTargetSize = size; 373 fRenderTargetState.fRenderTargetOrigin = rt->origin(); 374 375 float rtAdjustmentVec[4]; 376 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); 377 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); 378 } 379 } 380 381 void GrVkPipelineState::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) { 382 commandBuffer->bindPipeline(gpu, fPipeline); 383 384 if (fDSCount) { 385 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, fStartDS, fDSCount, 386 &fDescriptorSets[fStartDS], 0, nullptr); 387 } 388 } 389 390 void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) { 391 if (fUniformDescriptorSet) { 392 commandBuffer.addRecycledResource(fUniformDescriptorSet); 393 } 394 if (fSamplerDescriptorSet) { 395 commandBuffer.addRecycledResource(fSamplerDescriptorSet); 396 } 397 398 if (fVertexUniformBuffer.get()) { 399 commandBuffer.addRecycledResource(fVertexUniformBuffer->resource()); 400 } 401 if (fFragmentUniformBuffer.get()) { 402 commandBuffer.addRecycledResource(fFragmentUniformBuffer->resource()); 403 } 404 405 for (int i = 0; i < fSamplers.count(); ++i) { 406 commandBuffer.addResource(fSamplers[i]); 407 } 408 409 for (int i = 0; i < fTextureViews.count(); ++i) { 410 commandBuffer.addResource(fTextureViews[i]); 411 } 412 413 for (int i = 0; i < fTextures.count(); ++i) { 414 commandBuffer.addResource(fTextures[i]); 415 } 416 } 417 418 //////////////////////////////////////////////////////////////////////////////// 419 420 void GrVkPipelineState::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) { 421 if (fPool) { 422 fPool->unref(gpu); 423 uint32_t newPoolSize = fMaxDescriptors + ((fMaxDescriptors + 1) >> 1); 424 if (newPoolSize < kMaxDescLimit) { 425 fMaxDescriptors = newPoolSize; 426 } else { 427 fMaxDescriptors = kMaxDescLimit; 428 } 429 430 } 431 if (fMaxDescriptors) { 432 fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType, 433 fMaxDescriptors); 434 } 435 SkASSERT(fPool || !fMaxDescriptors); 436 } 437 438 void GrVkPipelineState::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu, 439 VkDescriptorSet* ds) { 440 if (!fMaxDescriptors) { 441 return; 442 } 443 fCurrentDescriptorCount += fDescCountPerSet; 444 if (fCurrentDescriptorCount > fMaxDescriptors) { 445 this->getNewPool(gpu); 446 fCurrentDescriptorCount = fDescCountPerSet; 447 } 448 449 VkDescriptorSetAllocateInfo dsAllocateInfo; 450 memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo)); 451 dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 452 dsAllocateInfo.pNext = nullptr; 453 dsAllocateInfo.descriptorPool = fPool->descPool(); 454 dsAllocateInfo.descriptorSetCount = 1; 455 dsAllocateInfo.pSetLayouts = &fDescLayout; 456 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), AllocateDescriptorSets(gpu->device(), 457 &dsAllocateInfo, 458 ds)); 459 } 460 461 void GrVkPipelineState::DescriptorPoolManager::freeGPUResources(const GrVkGpu* gpu) { 462 if (fDescLayout) { 463 GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout, 464 nullptr)); 465 fDescLayout = VK_NULL_HANDLE; 466 } 467 468 if (fPool) { 469 fPool->unref(gpu); 470 fPool = nullptr; 471 } 472 } 473 474 void GrVkPipelineState::DescriptorPoolManager::abandonGPUResources() { 475 fDescLayout = VK_NULL_HANDLE; 476 if (fPool) { 477 fPool->unrefAndAbandon(); 478 fPool = nullptr; 479 } 480 } 481 482 uint32_t get_blend_info_key(const GrPipeline& pipeline) { 483 GrXferProcessor::BlendInfo blendInfo; 484 pipeline.getXferProcessor().getBlendInfo(&blendInfo); 485 486 static const uint32_t kBlendWriteShift = 1; 487 static const uint32_t kBlendCoeffShift = 5; 488 GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift)); 489 GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4); 490 491 uint32_t key = blendInfo.fWriteColor; 492 key |= (blendInfo.fSrcBlend << kBlendWriteShift); 493 key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift)); 494 key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift)); 495 496 return key; 497 } 498 499 bool GrVkPipelineState::Desc::Build(Desc* desc, 500 const GrPrimitiveProcessor& primProc, 501 const GrPipeline& pipeline, 502 const GrStencilSettings& stencil, 503 GrPrimitiveType primitiveType, 504 const GrShaderCaps& caps) { 505 if (!INHERITED::Build(desc, primProc, primitiveType == kPoints_GrPrimitiveType, pipeline, 506 caps)) { 507 return false; 508 } 509 510 GrProcessorKeyBuilder b(&desc->key()); 511 GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget(); 512 vkRT->simpleRenderPass()->genKey(&b); 513 514 stencil.genKey(&b); 515 516 SkASSERT(sizeof(GrDrawFace) <= sizeof(uint32_t)); 517 b.add32((int32_t)pipeline.getDrawFace()); 518 519 b.add32(get_blend_info_key(pipeline)); 520 521 b.add32(primitiveType); 522 523 return true; 524 } 525