Index: src/gpu/vk/GrVkGpu.cpp |
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp |
index 76d50b0959beaaface643b798ebb55b25f7e0ee8..e779bac99baec1fb5d8bb15f22f36ae6afba6b55 100644 |
--- a/src/gpu/vk/GrVkGpu.cpp |
+++ b/src/gpu/vk/GrVkGpu.cpp |
@@ -777,8 +777,8 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
return; |
} |
- // We cannot generate mipmaps for images that are multisampled. |
- // TODO: does it even make sense for rendertargets in general? |
+ // We currently don't support generating mipmaps for images that are multisampled. |
+ // TODO: Add support for mipmapping the resolve target of a multisampled image |
if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) { |
return; |
} |
@@ -791,49 +791,56 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
return; |
} |
- // change the original image's layout |
- tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
- VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); |
- |
- // grab handle to the original image resource |
- const GrVkResource* oldResource = tex->resource(); |
- oldResource->ref(); |
- VkImage oldImage = tex->image(); |
+ int width = tex->width(); |
jvanverth1
2016/07/15 18:57:30
Move inside the conditional?
egdaniel
2016/07/15 19:02:06
It is used in the while loop (doing the blits) as
jvanverth1
2016/07/15 19:32:50
Ah, it was hidden. Cool beans.
|
+ int height = tex->height(); |
+ VkImageBlit blitRegion; |
+ memset(&blitRegion, 0, sizeof(VkImageBlit)); |
// 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; |
- } |
- |
- // change the new image's layout |
- tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, |
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); |
+ if (levelCount != tex->mipLevels()) { |
+ const GrVkResource* oldResource = tex->resource(); |
+ oldResource->ref(); |
+ // grab handle to the original image resource |
+ VkImage oldImage = tex->image(); |
+ |
+ // change the original image's layout so we can copy from it |
+ tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
+ VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); |
+ |
+ if (!tex->reallocForMipmap(this, levelCount)) { |
+ oldResource->unref(this); |
+ return; |
+ } |
+ // change the new image's layout so we can blit to it |
+ tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, |
+ VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); |
- // Blit original image |
- int width = tex->width(); |
- int height = tex->height(); |
+ // Blit original image to top level of new image |
+ blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
+ blitRegion.srcOffsets[0] = { 0, 0, 0 }; |
+ blitRegion.srcOffsets[1] = { width, height, 1 }; |
+ blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
+ blitRegion.dstOffsets[0] = { 0, 0, 0 }; |
+ blitRegion.dstOffsets[1] = { width, height, 1 }; |
- 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, 1 }; |
- blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
- blitRegion.dstOffsets[0] = { 0, 0, 0 }; |
- blitRegion.dstOffsets[1] = { width, height, 1 }; |
+ fCurrentCmdBuffer->blitImage(this, |
+ oldResource, |
+ oldImage, |
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
+ tex->resource(), |
+ tex->image(), |
+ VK_IMAGE_LAYOUT_GENERAL, |
+ 1, |
+ &blitRegion, |
+ VK_FILTER_LINEAR); |
- fCurrentCmdBuffer->blitImage(this, |
- oldResource, |
- oldImage, |
- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
- tex->resource(), |
- tex->image(), |
- VK_IMAGE_LAYOUT_GENERAL, |
- 1, |
- &blitRegion, |
- VK_FILTER_LINEAR); |
+ oldResource->unref(this); |
+ } else { |
+ // change layout of the layers so we can write to them. |
+ tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, |
+ VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); |
+ } |
// setup memory barrier |
SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr)); |
@@ -841,8 +848,8 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
VkImageMemoryBarrier imageMemoryBarrier = { |
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType |
NULL, // pNext |
- VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask |
- VK_ACCESS_TRANSFER_READ_BIT, // inputMask |
+ VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask |
+ VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask |
VK_IMAGE_LAYOUT_GENERAL, // oldLayout |
VK_IMAGE_LAYOUT_GENERAL, // newLayout |
VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex |
@@ -877,8 +884,6 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex) { |
VK_FILTER_LINEAR); |
++mipLevel; |
} |
- |
- oldResource->unref(this); |
} |
//////////////////////////////////////////////////////////////////////////////// |