OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrVkGpu.h" | 8 #include "GrVkGpu.h" |
9 | 9 |
10 #include "GrContextOptions.h" | 10 #include "GrContextOptions.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 SkASSERT(kDynamic_GrAccessPattern == accessPattern || | 242 SkASSERT(kDynamic_GrAccessPattern == accessPattern || |
243 kStatic_GrAccessPattern == accessPattern); | 243 kStatic_GrAccessPattern == accessPattern); |
244 buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern
== accessPattern); | 244 buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern
== accessPattern); |
245 break; | 245 break; |
246 case kIndex_GrBufferType: | 246 case kIndex_GrBufferType: |
247 SkASSERT(kDynamic_GrAccessPattern == accessPattern || | 247 SkASSERT(kDynamic_GrAccessPattern == accessPattern || |
248 kStatic_GrAccessPattern == accessPattern); | 248 kStatic_GrAccessPattern == accessPattern); |
249 buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern
== accessPattern); | 249 buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern
== accessPattern); |
250 break; | 250 break; |
251 case kXferCpuToGpu_GrBufferType: | 251 case kXferCpuToGpu_GrBufferType: |
252 SkASSERT(kStream_GrAccessPattern == accessPattern); | 252 SkASSERT(kDynamic_GrAccessPattern == accessPattern || |
| 253 kStream_GrAccessPattern == accessPattern); |
253 buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_
Type); | 254 buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_
Type); |
254 break; | 255 break; |
255 case kXferGpuToCpu_GrBufferType: | 256 case kXferGpuToCpu_GrBufferType: |
256 SkASSERT(kStream_GrAccessPattern == accessPattern); | 257 SkASSERT(kDynamic_GrAccessPattern == accessPattern || |
| 258 kStream_GrAccessPattern == accessPattern); |
257 buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite
_Type); | 259 buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite
_Type); |
258 break; | 260 break; |
259 default: | 261 default: |
260 SkFAIL("Unknown buffer type."); | 262 SkFAIL("Unknown buffer type."); |
261 return nullptr; | 263 return nullptr; |
262 } | 264 } |
263 if (data && buff) { | 265 if (data && buff) { |
264 buff->updateData(data, size); | 266 buff->updateData(data, size); |
265 } | 267 } |
266 return buff; | 268 return buff; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 return false; | 370 return false; |
369 } | 371 } |
370 } | 372 } |
371 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); | 373 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); |
372 } | 374 } |
373 } | 375 } |
374 | 376 |
375 return success; | 377 return success; |
376 } | 378 } |
377 | 379 |
| 380 bool GrVkGpu::onTransferPixels(GrTexture* texture, |
| 381 int left, int top, int width, int height, |
| 382 GrPixelConfig config, GrBuffer* transferBuffer, |
| 383 size_t bufferOffset, size_t rowBytes) { |
| 384 GrVkTexture* vkTex = static_cast<GrVkTexture*>(texture); |
| 385 if (!vkTex) { |
| 386 return false; |
| 387 } |
| 388 GrVkTransferBuffer* vkBuffer = static_cast<GrVkTransferBuffer*>(transferBuff
er); |
| 389 if (!vkBuffer) { |
| 390 return false; |
| 391 } |
| 392 |
| 393 // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and
writing pixels. |
| 394 if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) { |
| 395 return false; |
| 396 } |
| 397 |
| 398 // TODO: Handle y axis flip via copy to temp image, then blit to final |
| 399 if (kBottomLeft_GrSurfaceOrigin == vkTex->origin()) { |
| 400 return false; |
| 401 } |
| 402 |
| 403 bool success = false; |
| 404 if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) { |
| 405 // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo() |
| 406 SkASSERT(config == vkTex->desc().fConfig); |
| 407 // TODO: add compressed texture support |
| 408 // delete the following two lines and uncomment the two after that when
ready |
| 409 vkTex->unref(); |
| 410 return false; |
| 411 //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false,
left, top, width, |
| 412 // height); |
| 413 } else { |
| 414 // make sure the unmap has finished |
| 415 vkBuffer->addMemoryBarrier(this, |
| 416 VK_ACCESS_HOST_WRITE_BIT, |
| 417 VK_ACCESS_TRANSFER_READ_BIT, |
| 418 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
| 419 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 420 false); |
| 421 |
| 422 // Set up copy region |
| 423 size_t bpp = GrBytesPerPixel(config); |
| 424 |
| 425 VkBufferImageCopy region; |
| 426 memset(®ion, 0, sizeof(VkBufferImageCopy)); |
| 427 region.bufferOffset = bufferOffset; |
| 428 region.bufferRowLength = (uint32_t)(rowBytes/bpp); |
| 429 region.bufferImageHeight = 0; |
| 430 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
| 431 region.imageOffset = { left, top, 0 }; |
| 432 region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; |
| 433 |
| 434 // Change layout of our target so it can be copied to |
| 435 vkTex->setImageLayout(this, |
| 436 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| 437 VK_ACCESS_TRANSFER_WRITE_BIT, |
| 438 VK_PIPELINE_STAGE_TRANSFER_BIT, |
| 439 false); |
| 440 |
| 441 // Copy the buffer to the image |
| 442 fCurrentCmdBuffer->copyBufferToImage(this, |
| 443 vkBuffer, |
| 444 vkTex, |
| 445 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMA
L, |
| 446 1, |
| 447 ®ion); |
| 448 |
| 449 success = true; |
| 450 } |
| 451 |
| 452 if (success) { |
| 453 vkTex->texturePriv().dirtyMipMaps(true); |
| 454 return true; |
| 455 } |
| 456 |
| 457 return false; |
| 458 } |
| 459 |
378 void GrVkGpu::resolveImage(GrVkRenderTarget* dst, GrVkRenderTarget* src, const S
kIRect& srcRect, | 460 void GrVkGpu::resolveImage(GrVkRenderTarget* dst, GrVkRenderTarget* src, const S
kIRect& srcRect, |
379 const SkIPoint& dstPoint) { | 461 const SkIPoint& dstPoint) { |
380 SkASSERT(dst); | 462 SkASSERT(dst); |
381 SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); | 463 SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); |
382 | 464 |
383 if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { | 465 if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { |
384 this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); | 466 this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); |
385 } | 467 } |
386 | 468 |
387 // Flip rect if necessary | 469 // Flip rect if necessary |
(...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment | 1963 // Currently it is fine for us to always pass in 1 for the clear count even
if no attachment |
1882 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment | 1964 // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the
color attachment |
1883 // which is always at the first attachment. | 1965 // which is always at the first attachment. |
1884 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); | 1966 fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target,
*pBounds, true); |
1885 fCurrentCmdBuffer->executeCommands(this, buffer); | 1967 fCurrentCmdBuffer->executeCommands(this, buffer); |
1886 fCurrentCmdBuffer->endRenderPass(this); | 1968 fCurrentCmdBuffer->endRenderPass(this); |
1887 | 1969 |
1888 this->didWriteToSurface(target, &bounds); | 1970 this->didWriteToSurface(target, &bounds); |
1889 } | 1971 } |
1890 | 1972 |
| 1973 GrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() const { |
| 1974 VkFenceCreateInfo createInfo; |
| 1975 memset(&createInfo, 0, sizeof(VkFenceCreateInfo)); |
| 1976 createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; |
| 1977 createInfo.pNext = nullptr; |
| 1978 createInfo.flags = 0; |
| 1979 VkFence fence = VK_NULL_HANDLE; |
| 1980 VkResult result = GR_VK_CALL(this->vkInterface(), CreateFence(this->device()
, &createInfo, |
| 1981 nullptr, &fenc
e)); |
| 1982 // TODO: verify that all QueueSubmits before this will finish before this fe
nce signals |
| 1983 if (VK_SUCCESS == result) { |
| 1984 GR_VK_CALL(this->vkInterface(), QueueSubmit(this->queue(), 0, nullptr, f
ence)); |
| 1985 } |
| 1986 return (GrFence)fence; |
| 1987 } |
| 1988 |
| 1989 bool GrVkGpu::waitFence(GrFence fence) const { |
| 1990 const uint64_t kTimeout = 1000; |
| 1991 VkResult result = GR_VK_CALL(this->vkInterface(), WaitForFences(this->device
(), 1, |
| 1992 (VkFence*)&f
ence, |
| 1993 VK_TRUE, |
| 1994 kTimeout)); |
| 1995 return (VK_SUCCESS == result); |
| 1996 } |
| 1997 |
| 1998 void GrVkGpu::deleteFence(GrFence fence) const { |
| 1999 GR_VK_CALL(this->vkInterface(), DestroyFence(this->device(), (VkFence)fence,
nullptr)); |
| 2000 } |
| 2001 |
OLD | NEW |