| Index: src/gpu/vk/GrVkGpu.cpp
|
| diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
|
| index 7c101a7338871d458b6bdacd9dd02b05d62764cf..25bf250fea9110380d62bdec19fdb6bd38546c3f 100644
|
| --- a/src/gpu/vk/GrVkGpu.cpp
|
| +++ b/src/gpu/vk/GrVkGpu.cpp
|
| @@ -286,8 +286,8 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
|
| texels.begin()->fPixels, texels.begin()->fRowBytes);
|
| } else {
|
| int newMipLevels = texels.count();
|
| - int currentMipLevels = vkTex->texturePriv().maxMipMapLevel();
|
| - if ((currentMipLevels || newMipLevels != 1) && newMipLevels != currentMipLevels) {
|
| + int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1;
|
| + if (newMipLevels != currentMipLevels) {
|
| if (!vkTex->reallocForMipmap(this, newMipLevels)) {
|
| return false;
|
| }
|
| @@ -734,8 +734,9 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
|
| const GrVkImage::Resource* oldResource = tex->resource();
|
| oldResource->ref();
|
|
|
| - uint32_t mipLevels = SkMipMap::ComputeLevelCount(tex->width(), tex->height());
|
| - if (!tex->reallocForMipmap(this, mipLevels)) {
|
| + // SkMipMap doesn't include the base level in the level count so we have to add 1
|
| + uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height()) + 1;
|
| + if (!tex->reallocForMipmap(this, levelCount)) {
|
| oldResource->unref(this);
|
| return;
|
| }
|
| @@ -755,14 +756,13 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
|
| // Blit original image
|
| int width = tex->width();
|
| int height = tex->height();
|
| - uint32_t mipLevel = 0;
|
|
|
| VkImageBlit blitRegion;
|
| memset(&blitRegion, 0, sizeof(VkImageBlit));
|
| blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
| blitRegion.srcOffsets[0] = { 0, 0, 0 };
|
| blitRegion.srcOffsets[1] = { width, height, 0 };
|
| - blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 };
|
| + blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
| blitRegion.dstOffsets[0] = { 0, 0, 0 };
|
| blitRegion.dstOffsets[1] = { width, height, 0 };
|
|
|
| @@ -775,16 +775,23 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
|
| &blitRegion,
|
| VK_FILTER_LINEAR);
|
| // Blit the miplevels
|
| - while (width/2 > 0 && height/2 > 0) {
|
| - blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 };
|
| + uint32_t mipLevel = 1;
|
| + while (mipLevel < levelCount) {
|
| + int prevWidth = width;
|
| + int prevHeight = height;
|
| + width = SkTMax(1, width / 2);
|
| + height = SkTMax(1, height / 2);
|
| +
|
| + blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel-1, 0, 1 };
|
| blitRegion.srcOffsets[0] = { 0, 0, 0 };
|
| - blitRegion.srcOffsets[1] = { width, height, 0 };
|
| - blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel+1, 0, 1 };
|
| + blitRegion.srcOffsets[1] = { prevWidth, prevHeight, 0 };
|
| + blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 };
|
| blitRegion.dstOffsets[0] = { 0, 0, 0 };
|
| - blitRegion.dstOffsets[1] = { width/2, height/2, 0 };
|
| + blitRegion.dstOffsets[1] = { width, height, 0 };
|
|
|
| - // TODO: insert image barrier to wait on previous blit
|
| - // TODO: change layout of src subresource to TRANSFER_SRC_OPTIMAL
|
| + tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
| + srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
|
| + mipLevel-1, 1, false);
|
|
|
| fCurrentCmdBuffer->blitImage(this,
|
| tex->resource(),
|
| @@ -794,17 +801,13 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
|
| 1,
|
| &blitRegion,
|
| VK_FILTER_LINEAR);
|
| -
|
| - width /= 2;
|
| - height /= 2;
|
| - mipLevel++;
|
| + ++mipLevel;
|
| }
|
|
|
| oldResource->unref(this);
|
| }
|
|
|
|
|
| -
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
|
|
|