Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: src/gpu/vk/GrVkGpu.cpp

Issue 1940963002: Fix VK WritePixels with offset rect (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clamp miplevel dimensions to be at least 1" Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 &currentWidth,
427 &currentHeight,
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(&region, 0, sizeof(VkBufferImageCopy)); 467 memset(&region, 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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698