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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 VK_IMAGE_LAYOUT_GENERAL, | 276 VK_IMAGE_LAYOUT_GENERAL, |
277 srcAccessMask, | 277 srcAccessMask, |
278 dstAccessMask, | 278 dstAccessMask, |
279 srcStageMask, | 279 srcStageMask, |
280 dstStageMask, | 280 dstStageMask, |
281 false); | 281 false); |
282 } | 282 } |
283 success = this->uploadTexDataLinear(vkTex, left, top, width, height,
config, | 283 success = this->uploadTexDataLinear(vkTex, left, top, width, height,
config, |
284 texels.begin()->fPixels, texels.
begin()->fRowBytes); | 284 texels.begin()->fPixels, texels.
begin()->fRowBytes); |
285 } else { | 285 } else { |
286 int mipLevels = texels.count(); | 286 int newMipLevels = texels.count(); |
287 if (vkTex->texturePriv().maxMipMapLevel() != mipLevels) { | 287 int currentMipLevels = vkTex->texturePriv().maxMipMapLevel(); |
288 if (!vkTex->reallocForMipmap(this, mipLevels)) { | 288 if ((currentMipLevels || newMipLevels != 1) && newMipLevels != curre
ntMipLevels) { |
| 289 if (!vkTex->reallocForMipmap(this, newMipLevels)) { |
289 return false; | 290 return false; |
290 } | 291 } |
291 } | 292 } |
292 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); | 293 success = this->uploadTexDataOptimal(vkTex, left, top, width, height
, config, texels); |
293 } | 294 } |
294 } | 295 } |
295 | 296 |
296 return success; | 297 return success; |
297 } | 298 } |
298 | 299 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 | 383 |
383 if (width == 0 || height == 0) { | 384 if (width == 0 || height == 0) { |
384 return false; | 385 return false; |
385 } | 386 } |
386 | 387 |
387 const GrSurfaceDesc& desc = tex->desc(); | 388 const GrSurfaceDesc& desc = tex->desc(); |
388 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); | 389 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); |
389 size_t bpp = GrBytesPerPixel(dataConfig); | 390 size_t bpp = GrBytesPerPixel(dataConfig); |
390 | 391 |
391 // texels is const. | 392 // texels is const. |
392 // But we may need to adjust the fPixels ptr based on the copyRect. | 393 // But we may need to adjust the fPixels ptr based on the copyRect, or fRowB
ytes. |
393 // In this case we need to make a non-const shallow copy of texels. | 394 // Because of this we need to make a non-const shallow copy of texels. |
394 const SkTArray<GrMipLevel>* texelsPtr = &texels; | 395 SkTArray<GrMipLevel> texelsShallowCopy(texels); |
395 SkTArray<GrMipLevel> texelsCopy; | |
396 if (0 != left || 0 != top || width != tex->width() || height != tex->height(
)) { | |
397 texelsCopy = texels; | |
398 | 396 |
399 SkASSERT(1 == texels.count()); | 397 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >=
0; |
400 SkASSERT(texelsCopy[0].fPixels); | 398 currentMipLevel--) { |
401 | 399 SkASSERT(texelsShallowCopy[currentMipLevel].fPixels); |
402 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp
p, &left, &top, | |
403 &width, &height, &texelsCopy[
0].fPixels, | |
404 &texelsCopy[0].fRowBytes)) { | |
405 return false; | |
406 } | |
407 | |
408 texelsPtr = &texelsCopy; | |
409 } | 400 } |
410 | 401 |
411 // Determine whether we need to flip when we copy into the buffer | 402 // Determine whether we need to flip when we copy into the buffer |
412 bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsPtr->emp
ty()); | 403 bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowC
opy.empty()); |
413 | 404 |
| 405 // adjust any params (left, top, currentWidth, currentHeight |
414 // find the combined size of all the mip levels and the relative offset of | 406 // find the combined size of all the mip levels and the relative offset of |
415 // each into the collective buffer | 407 // each into the collective buffer |
416 size_t combinedBufferSize = 0; | 408 // Do the first level separately because we may need to adjust width and hei
ght |
417 SkTArray<size_t> individualMipOffsets(texelsPtr->count()); | 409 // (for the non-mipped case). |
418 for (int currentMipLevel = 0; currentMipLevel < texelsPtr->count(); currentM
ipLevel++) { | 410 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &
left, &top, |
419 int twoToTheMipLevel = 1 << currentMipLevel; | 411 &width, |
420 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 412 &height, |
421 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 413 &texelsShallowCopy[0].fPixels, |
| 414 &texelsShallowCopy[0].fRowBytes))
{ |
| 415 return false; |
| 416 } |
| 417 SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count()); |
| 418 individualMipOffsets.push_back(0); |
| 419 size_t combinedBufferSize = width * bpp * height; |
| 420 int currentWidth = width; |
| 421 int currentHeight = height; |
| 422 for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { |
| 423 currentWidth = SkTMax(1, currentWidth/2); |
| 424 currentHeight = SkTMax(1, currentHeight/2); |
| 425 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp
p, &left, &top, |
| 426 ¤tWidth, |
| 427 ¤tHeight, |
| 428 &texelsShallowCopy[currentMip
Level].fPixels, |
| 429 &texelsShallowCopy[currentMip
Level].fRowBytes)) { |
| 430 return false; |
| 431 } |
422 const size_t trimmedSize = currentWidth * bpp * currentHeight; | 432 const size_t trimmedSize = currentWidth * bpp * currentHeight; |
423 individualMipOffsets.push_back(combinedBufferSize); | 433 individualMipOffsets.push_back(combinedBufferSize); |
424 combinedBufferSize += trimmedSize; | 434 combinedBufferSize += trimmedSize; |
425 } | 435 } |
426 | 436 |
427 // allocate buffer to hold our mip data | 437 // allocate buffer to hold our mip data |
428 GrVkTransferBuffer* transferBuffer = | 438 GrVkTransferBuffer* transferBuffer = |
429 GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuff
er::kCopyRead_Type); | 439 GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuff
er::kCopyRead_Type); |
430 | 440 |
431 char* buffer = (char*) transferBuffer->map(); | 441 char* buffer = (char*) transferBuffer->map(); |
432 SkTArray<VkBufferImageCopy> regions(texelsPtr->count()); | 442 SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count()); |
433 | 443 |
434 for (int currentMipLevel = 0; currentMipLevel < texelsPtr->count(); currentM
ipLevel++) { | 444 currentWidth = width; |
435 int twoToTheMipLevel = 1 << currentMipLevel; | 445 currentHeight = height; |
436 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 446 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { |
437 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | |
438 const size_t trimRowBytes = currentWidth * bpp; | 447 const size_t trimRowBytes = currentWidth * bpp; |
439 const size_t rowBytes = (*texelsPtr)[currentMipLevel].fRowBytes; | 448 const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; |
440 | 449 |
441 // copy data into the buffer, skipping the trailing bytes | 450 // copy data into the buffer, skipping the trailing bytes |
442 char* dst = buffer + individualMipOffsets[currentMipLevel]; | 451 char* dst = buffer + individualMipOffsets[currentMipLevel]; |
443 const char* src = (const char*)(*texelsPtr)[currentMipLevel].fPixels; | 452 const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixel
s; |
444 if (flipY) { | 453 if (flipY) { |
445 src += (currentHeight - 1) * rowBytes; | 454 src += (currentHeight - 1) * rowBytes; |
446 for (int y = 0; y < currentHeight; y++) { | 455 for (int y = 0; y < currentHeight; y++) { |
447 memcpy(dst, src, trimRowBytes); | 456 memcpy(dst, src, trimRowBytes); |
448 src -= rowBytes; | 457 src -= rowBytes; |
449 dst += trimRowBytes; | 458 dst += trimRowBytes; |
450 } | 459 } |
451 } else if (trimRowBytes == rowBytes) { | 460 } else if (trimRowBytes == rowBytes) { |
452 memcpy(dst, src, trimRowBytes * currentHeight); | 461 memcpy(dst, src, trimRowBytes * currentHeight); |
453 } else { | 462 } else { |
454 SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, current
Height); | 463 SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, current
Height); |
455 } | 464 } |
456 | 465 |
457 VkBufferImageCopy& region = regions.push_back(); | 466 VkBufferImageCopy& region = regions.push_back(); |
458 memset(®ion, 0, sizeof(VkBufferImageCopy)); | 467 memset(®ion, 0, sizeof(VkBufferImageCopy)); |
459 region.bufferOffset = individualMipOffsets[currentMipLevel]; | 468 region.bufferOffset = individualMipOffsets[currentMipLevel]; |
460 region.bufferRowLength = currentWidth; | 469 region.bufferRowLength = currentWidth; |
461 region.bufferImageHeight = currentHeight; | 470 region.bufferImageHeight = currentHeight; |
462 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMi
pLevel), 0, 1 }; | 471 region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMi
pLevel), 0, 1 }; |
463 region.imageOffset = { left, top, 0 }; | 472 region.imageOffset = { left, flipY ? tex->height() - top - currentHeight
: top, 0 }; |
464 region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight,
1 }; | 473 region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight,
1 }; |
| 474 |
| 475 currentWidth = SkTMax(1, currentWidth/2); |
| 476 currentHeight = SkTMax(1, currentHeight/2); |
465 } | 477 } |
466 | 478 |
467 transferBuffer->unmap(); | 479 transferBuffer->unmap(); |
468 | 480 |
469 // make sure the unmap has finished | 481 // make sure the unmap has finished |
470 transferBuffer->addMemoryBarrier(this, | 482 transferBuffer->addMemoryBarrier(this, |
471 VK_ACCESS_HOST_WRITE_BIT, | 483 VK_ACCESS_HOST_WRITE_BIT, |
472 VK_ACCESS_TRANSFER_READ_BIT, | 484 VK_ACCESS_TRANSFER_READ_BIT, |
473 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, | 485 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
474 VK_PIPELINE_STAGE_TRANSFER_BIT, | 486 VK_PIPELINE_STAGE_TRANSFER_BIT, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 // both bits, we must make sure to set the destination bit if we are uploadi
ng srcData to the | 558 // both bits, we must make sure to set the destination bit if we are uploadi
ng srcData to the |
547 // texture. | 559 // texture. |
548 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_
BIT; | 560 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_
BIT; |
549 | 561 |
550 VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HO
ST_VISIBLE_BIT : | 562 VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HO
ST_VISIBLE_BIT : |
551 VK_MEMORY_PROPERTY_DE
VICE_LOCAL_BIT; | 563 VK_MEMORY_PROPERTY_DE
VICE_LOCAL_BIT; |
552 | 564 |
553 // This ImageDesc refers to the texture that will be read by the client. Thu
s even if msaa is | 565 // This ImageDesc refers to the texture that will be read by the client. Thu
s even if msaa is |
554 // requested, this ImageDesc describes the resolved texture. Therefore we al
ways have samples set | 566 // requested, this ImageDesc describes the resolved texture. Therefore we al
ways have samples set |
555 // to 1. | 567 // to 1. |
| 568 int mipLevels = texels.empty() ? 1 : texels.count(); |
556 GrVkImage::ImageDesc imageDesc; | 569 GrVkImage::ImageDesc imageDesc; |
557 imageDesc.fImageType = VK_IMAGE_TYPE_2D; | 570 imageDesc.fImageType = VK_IMAGE_TYPE_2D; |
558 imageDesc.fFormat = pixelFormat; | 571 imageDesc.fFormat = pixelFormat; |
559 imageDesc.fWidth = desc.fWidth; | 572 imageDesc.fWidth = desc.fWidth; |
560 imageDesc.fHeight = desc.fHeight; | 573 imageDesc.fHeight = desc.fHeight; |
561 imageDesc.fLevels = linearTiling ? 1 : texels.count(); | 574 imageDesc.fLevels = linearTiling ? 1 : mipLevels; |
562 imageDesc.fSamples = 1; | 575 imageDesc.fSamples = 1; |
563 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; | 576 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; |
564 imageDesc.fUsageFlags = usageFlags; | 577 imageDesc.fUsageFlags = usageFlags; |
565 imageDesc.fMemProps = memProps; | 578 imageDesc.fMemProps = memProps; |
566 | 579 |
567 GrVkTexture* tex; | 580 GrVkTexture* tex; |
568 if (renderTarget) { | 581 if (renderTarget) { |
569 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budget
ed, desc, | 582 tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budget
ed, desc, |
570 imageDesc); | 583 imageDesc); |
571 } else { | 584 } else { |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1794 aglSwapBuffers(aglGetCurrentContext()); | 1807 aglSwapBuffers(aglGetCurrentContext()); |
1795 int set_a_break_pt_here = 9; | 1808 int set_a_break_pt_here = 9; |
1796 aglSwapBuffers(aglGetCurrentContext()); | 1809 aglSwapBuffers(aglGetCurrentContext()); |
1797 #elif defined(SK_BUILD_FOR_WIN32) | 1810 #elif defined(SK_BUILD_FOR_WIN32) |
1798 SwapBuf(); | 1811 SwapBuf(); |
1799 int set_a_break_pt_here = 9; | 1812 int set_a_break_pt_here = 9; |
1800 SwapBuf(); | 1813 SwapBuf(); |
1801 #endif | 1814 #endif |
1802 #endif | 1815 #endif |
1803 } | 1816 } |
OLD | NEW |