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

Unified Diff: src/gpu/vk/GrVkGpu.cpp

Issue 1916563002: Add automatic generation of mipmaps to Vulkan (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkImageView.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/vk/GrVkGpu.cpp
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 4d0ecbf5ea14b096ff164e4d75438caf0f0b8fed..76fe92abc1ec3860b298a004537ff7132029e880 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -469,7 +469,7 @@ GrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budget
// For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and
// VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we
// will be using this texture in some copy or not. Also this assumes, as is the current case,
- // that all render targets in vulkan are also texutres. If we change this practice of setting
+ // that all render targets in vulkan are also textures. If we change this practice of setting
// both bits, we must make sure to set the destination bit if we are uploading srcData to the
// texture.
usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
@@ -478,14 +478,14 @@ GrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budget
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
// This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is
- // requested, this ImageDesc describes the resolved texutre. Therefore we always have samples set
+ // requested, this ImageDesc describes the resolved texture. Therefore we always have samples set
// to 1.
GrVkImage::ImageDesc imageDesc;
imageDesc.fImageType = VK_IMAGE_TYPE_2D;
imageDesc.fFormat = pixelFormat;
imageDesc.fWidth = desc.fWidth;
imageDesc.fHeight = desc.fHeight;
- imageDesc.fLevels = 1;
+ imageDesc.fLevels = 1; // TODO: support miplevels for optimal tiling
imageDesc.fSamples = 1;
imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
imageDesc.fUsageFlags = usageFlags;
@@ -606,6 +606,112 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
return tgt;
}
+void GrVkGpu::generateMipmap(GrVkTexture* tex) const {
+ // don't need to do anything for linearly tiled textures (can't have mipmaps)
+ if (tex->isLinearTiled()) {
+ return;
+ }
+
+ // We cannot generate mipmaps for images that are multisampled.
+ // TODO: does it even make sense for rendertargets in general?
+ if (tex->asRenderTarget() && tex->asRenderTarget()->numColorSamples() > 1) {
+ return;
+ }
+
+ // determine if we can blit to and from this format
+ const GrVkCaps& caps = this->vkCaps();
+ if (!caps.configCanBeDstofBlit(tex->config(), false) ||
+ !caps.configCanBeSrcofBlit(tex->config(), false)) {
+ return;
+ }
+
+ // change the original image's layout
+ VkImageLayout origSrcLayout = tex->currentLayout();
+ VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origSrcLayout);
+ VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+
+ VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origSrcLayout);
+ VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+
+ tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ srcAccessMask, dstAccessMask, srcStageMask, dstStageMask, false);
+
+ // grab handle to the original image resource
+ const GrVkImage::Resource* oldResource = tex->resource();
+ oldResource->ref();
+
+ if (!tex->reallocForMipmap(this)) {
+ oldResource->unref(this);
+ return;
+ }
+
+ // change the new image's layout
+ VkImageLayout origDstLayout = tex->currentLayout();
+
+ srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout);
+ dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+
+ srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);
+ dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+
+ tex->setImageLayout(this,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ srcAccessMask,
+ dstAccessMask,
+ srcStageMask,
+ dstStageMask,
+ false);
+
+ // 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.dstOffsets[0] = { 0, 0, 0 };
+ blitRegion.dstOffsets[1] = { width, height, 0 };
+
+ fCurrentCmdBuffer->blitImage(this,
+ oldResource,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ tex->resource(),
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ 1,
+ &blitRegion,
+ VK_FILTER_LINEAR);
+ // Blit the miplevels
+ while (width/2 > 0 && height/2 > 0) {
+ blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 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.dstOffsets[0] = { 0, 0, 0 };
+ blitRegion.dstOffsets[1] = { width/2, height/2, 0 };
+
+ fCurrentCmdBuffer->blitImage(this,
+ tex->resource(),
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ tex->resource(),
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ 1,
+ &blitRegion,
+ VK_FILTER_LINEAR);
+
+ width /= 2;
+ height /= 2;
+ mipLevel++;
+ }
+
+ oldResource->unref(this);
+}
+
+
+
////////////////////////////////////////////////////////////////////////////////
void GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc,
@@ -1268,9 +1374,9 @@ void GrVkGpu::copySurfaceAsBlit(GrSurface* dst,
blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 0 };
fCurrentCmdBuffer->blitImage(this,
- srcImage,
+ srcImage->resource(),
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- dstImage,
+ dstImage->resource(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&blitRegion,
« no previous file with comments | « src/gpu/vk/GrVkGpu.h ('k') | src/gpu/vk/GrVkImageView.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698