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

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: 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++) {
egdaniel 2016/05/02 17:38:23 In this loop I notice you removed the SkTMax to ke
jvanverth1 2016/05/02 17:46:08 Whoops, fixed.
423 currentWidth /= 2;
424 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 /= 2;
476 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 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 aglSwapBuffers(aglGetCurrentContext()); 1806 aglSwapBuffers(aglGetCurrentContext());
1795 int set_a_break_pt_here = 9; 1807 int set_a_break_pt_here = 9;
1796 aglSwapBuffers(aglGetCurrentContext()); 1808 aglSwapBuffers(aglGetCurrentContext());
1797 #elif defined(SK_BUILD_FOR_WIN32) 1809 #elif defined(SK_BUILD_FOR_WIN32)
1798 SwapBuf(); 1810 SwapBuf();
1799 int set_a_break_pt_here = 9; 1811 int set_a_break_pt_here = 9;
1800 SwapBuf(); 1812 SwapBuf();
1801 #endif 1813 #endif
1802 #endif 1814 #endif
1803 } 1815 }
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