aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2016-05-03 11:19:01 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-03 11:19:01 -0700
commit82c0558d93b15e13f5ad431eeef44055af25bbcb (patch)
tree7c95d6bb4f951191b5c80a0064db8b7102fd756c /src/gpu
parentc8ef053e3dc48c8f1c74828fb56d0eed887f67c3 (diff)
Set barriers and image layout changes between mipmap blits.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/vk/GrVkGpu.cpp39
-rw-r--r--src/gpu/vk/GrVkImage.cpp4
-rw-r--r--src/gpu/vk/GrVkImage.h13
-rw-r--r--src/gpu/vk/GrVkTextureRenderTarget.cpp2
4 files changed, 38 insertions, 20 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 7c101a7338..25bf250fea 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,
diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp
index 53fb2f2bb7..0c3a297c1a 100644
--- a/src/gpu/vk/GrVkImage.cpp
+++ b/src/gpu/vk/GrVkImage.cpp
@@ -30,6 +30,8 @@ void GrVkImage::setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout,
VkAccessFlags dstAccessMask,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
+ uint32_t baseMipLevel,
+ uint32_t levelCount,
bool byRegion) {
SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED != newLayout &&
VK_IMAGE_LAYOUT_PREINITIALIZED != newLayout);
@@ -49,7 +51,7 @@ void GrVkImage::setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout,
VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
fResource->fImage, // image
- { aspectFlags, 0, fResource->fLevelCount, 0, 1 } // subresourceRange
+ { aspectFlags, baseMipLevel, levelCount, 0, 1 } // subresourceRange
};
// TODO: restrict to area of image we're interested in
diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h
index 6f848d52e4..006c0f1983 100644
--- a/src/gpu/vk/GrVkImage.h
+++ b/src/gpu/vk/GrVkImage.h
@@ -92,6 +92,19 @@ public:
VkAccessFlags dstAccessMask,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
+ bool byRegion) {
+ this->setImageLayout(gpu, newLayout, srcAccessMask, dstAccessMask,
+ srcStageMask, dstStageMask, 0, fResource->fLevelCount, byRegion);
+ }
+
+ void setImageLayout(const GrVkGpu* gpu,
+ VkImageLayout newLayout,
+ VkAccessFlags srcAccessMask,
+ VkAccessFlags dstAccessMask,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ uint32_t baseMipLevel,
+ uint32_t levelCount,
bool byRegion);
struct ImageDesc {
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index 2a89817713..c33a6800b8 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -29,7 +29,7 @@ GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
uint32_t mipLevels = 1;
//TODO: does a mipmapped textureRenderTarget make sense?
//if (desc.fIsMipMapped) {
- // mipLevels = SkMipMap::ComputeLevelCount(this->width(), this->height());
+ // mipLevels = SkMipMap::ComputeLevelCount(this->width(), this->height()) + 1;
//}
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
GrVkImageView::kColor_Type, mipLevels);