Revise GrDataUtils to be more self-contained (take 3)
This makes the GL and Vk backends share more code and sets up for the Metal implementation.
Change-Id: I781d5b6188fb2d46ae4ec48204fda74fe28b18c0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218964
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 8b4de2d..965251e 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -117,7 +117,8 @@
return numBlocks * sizeof(ETC1Block);
}
-void GrFillInETC1WithColor(int width, int height, const SkColor4f& colorf, void* dest) {
+// Fill in 'dest' with ETC1 blocks derived from 'colorf'
+static void fillin_ETC1_with_color(int width, int height, const SkColor4f& colorf, void* dest) {
SkColor color = colorf.toSkColor();
ETC1Block block;
@@ -130,8 +131,9 @@
}
}
-bool GrFillBufferWithColor(GrPixelConfig config, int width, int height,
- const SkColor4f& colorf, void* dest) {
+// Fill in the width x height 'dest' with the munged version of 'colorf' that matches 'config'
+static bool fill_buffer_with_color(GrPixelConfig config, int width, int height,
+ const SkColor4f& colorf, void* dest) {
SkASSERT(kRGB_ETC1_GrPixelConfig != config);
GrColor color = colorf.toBytes_RGBA();
@@ -282,3 +284,78 @@
return true;
}
+
+size_t GrComputeTightCombinedBufferSize(GrCompression compression, size_t bytesPerPixel,
+ int baseWidth, int baseHeight,
+ SkTArray<size_t>* individualMipOffsets,
+ int mipLevelCount) {
+ SkASSERT(individualMipOffsets && !individualMipOffsets->count());
+ SkASSERT(mipLevelCount >= 1);
+
+ individualMipOffsets->push_back(0);
+
+ size_t combinedBufferSize = baseWidth * bytesPerPixel * baseHeight;
+ if (GrCompression::kETC1 == compression) {
+ SkASSERT(0 == bytesPerPixel);
+ bytesPerPixel = 4; // munge Bpp to make the following code work (and not assert)
+ combinedBufferSize = GrETC1CompressedDataSize(baseWidth, baseHeight);
+ }
+
+ int currentWidth = baseWidth;
+ int currentHeight = baseHeight;
+
+ // The Vulkan spec for copying a buffer to an image requires that the alignment must be at
+ // least 4 bytes and a multiple of the bytes per pixel of the image config.
+ SkASSERT(bytesPerPixel == 1 || bytesPerPixel == 2 || bytesPerPixel == 3 ||
+ bytesPerPixel == 4 || bytesPerPixel == 8 || bytesPerPixel == 16);
+ int desiredAlignment = (bytesPerPixel == 3) ? 12 : (bytesPerPixel > 4 ? bytesPerPixel : 4);
+
+ for (int currentMipLevel = 1; currentMipLevel < mipLevelCount; ++currentMipLevel) {
+ currentWidth = SkTMax(1, currentWidth / 2);
+ currentHeight = SkTMax(1, currentHeight / 2);
+
+ size_t trimmedSize;
+ if (GrCompression::kETC1 == compression) {
+ trimmedSize = GrETC1CompressedDataSize(currentWidth, currentHeight);
+ } else {
+ trimmedSize = currentWidth * bytesPerPixel * currentHeight;
+ }
+ const size_t alignmentDiff = combinedBufferSize % desiredAlignment;
+ if (alignmentDiff != 0) {
+ combinedBufferSize += desiredAlignment - alignmentDiff;
+ }
+ SkASSERT((0 == combinedBufferSize % 4) && (0 == combinedBufferSize % bytesPerPixel));
+
+ individualMipOffsets->push_back(combinedBufferSize);
+ combinedBufferSize += trimmedSize;
+ }
+
+ SkASSERT(individualMipOffsets->count() == mipLevelCount);
+ return combinedBufferSize;
+}
+
+void GrFillInData(GrCompression compression, GrPixelConfig config,
+ int baseWidth, int baseHeight,
+ const SkTArray<size_t>& individualMipOffsets, char* dstPixels,
+ const SkColor4f& colorf) {
+
+ int mipLevels = individualMipOffsets.count();
+
+ int currentWidth = baseWidth;
+ int currentHeight = baseHeight;
+ for (int currentMipLevel = 0; currentMipLevel < mipLevels; ++currentMipLevel) {
+ size_t offset = individualMipOffsets[currentMipLevel];
+
+ if (GrCompression::kETC1 == compression) {
+ // TODO: compute the ETC1 block for 'colorf' just once
+ fillin_ETC1_with_color(currentWidth, currentHeight, colorf, &(dstPixels[offset]));
+ } else {
+ fill_buffer_with_color(config, currentWidth, currentHeight, colorf,
+ &(dstPixels[offset]));
+ }
+
+ currentWidth = SkTMax(1, currentWidth / 2);
+ currentHeight = SkTMax(1, currentHeight / 2);
+ }
+}
+
diff --git a/src/gpu/GrDataUtils.h b/src/gpu/GrDataUtils.h
index bdcbd66..b79e84c 100644
--- a/src/gpu/GrDataUtils.h
+++ b/src/gpu/GrDataUtils.h
@@ -11,15 +11,26 @@
#include "include/core/SkColor.h"
#include "include/private/GrTypesPriv.h"
-// Fill in the width x height 'dest' with the munged version of 'color' that matches 'config'
-bool GrFillBufferWithColor(GrPixelConfig config, int width, int height,
- const SkColor4f& color, void* dest);
-
// TODO: consolidate all the backend-specific flavors of this method to this
size_t GrETC1CompressedDataSize(int w, int h);
-// Fill in 'dest' with ETC1 blocks derived from 'color'
-void GrFillInETC1WithColor(int width, int height,
- const SkColor4f& color, void* dest);
+// TODO: should this be grown into a replacement for GrPixelConfig?
+enum class GrCompression {
+ kNone,
+ kETC1,
+};
+
+// Compute the size of the buffer required to hold all the mipLevels of the specified type
+// of data when all rowBytes are tight.
+// Note there may still be padding between the mipLevels to meet alignment requirements.
+size_t GrComputeTightCombinedBufferSize(GrCompression, size_t bytesPerPixel,
+ int baseWidth, int baseHeight,
+ SkTArray<size_t>* individualMipOffsets,
+ int mipLevelCount);
+
+void GrFillInData(GrCompression, GrPixelConfig,
+ int baseWidth, int baseHeight,
+ const SkTArray<size_t>& individualMipOffsets,
+ char* dest, const SkColor4f& color);
#endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index f344e2e..d2b18f1 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1589,50 +1589,6 @@
return state;
}
-size_t GLBytesPerPixel(GrGLenum glFormat) {
- switch (glFormat) {
- case GR_GL_LUMINANCE8:
- case GR_GL_ALPHA8:
- case GR_GL_R8:
- return 1;
-
- case GR_GL_RGB565:
- case GR_GL_RGBA4:
- case GR_GL_RG8:
- case GR_GL_R16F:
- return 2;
-
- case GR_GL_RGB8:
- return 3;
-
- case GR_GL_RGBA8:
- case GR_GL_SRGB8_ALPHA8:
- case GR_GL_BGRA8:
- case GR_GL_RGB10_A2:
- return 4;
-
- case GR_GL_RGBA16F:
- case GR_GL_RG32F:
- return 8;
-
- case GR_GL_RGBA32F:
- return 16;
-
- case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
- case GR_GL_COMPRESSED_ETC1_RGB8:
- return 0;
-
- // Experimental (for P016 and P010)
- case GR_GL_R16:
- return 2;
- case GR_GL_RG16:
- return 4;
- }
-
- SK_ABORT("Invalid GL format");
- return 0;
-}
-
sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
SkBudgeted budgeted,
const GrMipLevel texels[],
@@ -1652,7 +1608,7 @@
std::unique_ptr<uint8_t[]> zeros;
if (performClear && !this->glCaps().clearTextureSupport() &&
!this->glCaps().canConfigBeFBOColorAttachment(desc.fConfig)) {
- size_t rowSize = GLBytesPerPixel(glFormat) * desc.fWidth;
+ size_t rowSize = GrGLBytesPerFormat(glFormat) * desc.fWidth;
size_t size = rowSize * desc.fHeight;
zeros.reset(new uint8_t[size]);
memset(zeros.get(), 0, size);
@@ -4050,7 +4006,7 @@
const GrBackendFormat& format,
GrMipMapped mipMapped,
GrRenderable renderable,
- const void* pixels, size_t rowBytes,
+ const void* srcPixels, size_t rowBytes,
const SkColor4f& colorf) {
this->handleDirtyContext();
@@ -4075,7 +4031,7 @@
}
// Currently we don't support uploading pixel data when mipped.
- if (pixels && GrMipMapped::kYes == mipMapped) {
+ if (srcPixels && GrMipMapped::kYes == mipMapped) {
return GrBackendTexture(); // invalid
}
@@ -4089,43 +4045,39 @@
mipLevelCount = SkMipMap::ComputeLevelCount(w, h) + 1;
}
- SkAutoMalloc pixelStorage;
-
- if (GrGLFormatIsCompressed(*glFormat)) {
- // we have to do something special for compressed textures
- SkASSERT(0 == rowBytes);
-
- if (!pixels) {
- size_t etc1Size = GrGLFormatCompressedDataSize(*glFormat, w, h);
- pixelStorage.reset(etc1Size);
- GrFillInETC1WithColor(w, h, colorf, pixelStorage.get());
- pixels = pixelStorage.get();
- rowBytes = 0;
- }
- } else {
- int bpp = GrBytesPerPixel(config);
- const size_t trimRowBytes = w * bpp;
- if (!rowBytes) {
- rowBytes = trimRowBytes;
- }
-
- if (!pixels) {
- size_t baseLayerSize = trimRowBytes * h;
- pixelStorage.reset(baseLayerSize);
- if (!GrFillBufferWithColor(config, w, h, colorf, pixelStorage.get())) {
- return GrBackendTexture(); // invalid
- }
-
- pixels = pixelStorage.get();
- rowBytes = trimRowBytes;
- }
- }
-
SkAutoTMalloc<GrMipLevel> texels(mipLevelCount);
- for (int i = 0; i < mipLevelCount; ++i) {
- // TODO: this isn't correct when pixels for additional mip levels are passed in
- texels.get()[i] = { pixels, rowBytes };
+ SkAutoMalloc pixelStorage;
+
+ if (!srcPixels) {
+ GrCompression compression = GrGLFormat2Compression(*glFormat);
+
+ SkTArray<size_t> individualMipOffsets(mipLevelCount);
+ size_t bytesPerPixel = GrBytesPerPixel(config);
+
+ size_t totalSize = GrComputeTightCombinedBufferSize(compression, bytesPerPixel, w, h,
+ &individualMipOffsets, mipLevelCount);
+
+ char* tmpPixels = (char *) pixelStorage.reset(totalSize);
+
+ GrFillInData(compression, config, w, h, individualMipOffsets, tmpPixels, colorf);
+
+ for (int i = 0; i < mipLevelCount; ++i) {
+ size_t offset = individualMipOffsets[i];
+
+ int twoToTheMipLevel = 1 << i;
+ int currentWidth = SkTMax(1, w / twoToTheMipLevel);
+
+ texels.get()[i] = { &(tmpPixels[offset]), currentWidth*bytesPerPixel };
+ }
+ } else {
+ SkASSERT(1 == mipLevelCount);
+
+ if (GrGLFormatIsCompressed(*glFormat)) {
+ SkASSERT(0 == rowBytes);
+ }
+
+ texels.get()[0] = { srcPixels, rowBytes };
}
GrSurfaceDesc desc;
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 8f67be7..f50932e 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -573,6 +573,18 @@
return false;
}
+GrCompression GrGLFormat2Compression(GrGLenum glFormat) {
+ switch (glFormat) {
+ case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
+ case GR_GL_COMPRESSED_ETC1_RGB8:
+ return GrCompression::kETC1;
+ default:
+ return GrCompression::kNone;
+ }
+ SK_ABORT("Invalid format");
+ return GrCompression::kNone;
+}
+
size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height) {
SkASSERT(GrGLFormatIsCompressed(glFormat));
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index c9bd3c2..332cddd 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -10,6 +10,7 @@
#include "include/gpu/gl/GrGLInterface.h"
#include "include/private/GrTypesPriv.h"
+#include "src/gpu/GrDataUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/gl/GrGLDefines.h"
@@ -265,6 +266,11 @@
bool GrGLFormatIsCompressed(GrGLenum glFormat);
/**
+ * Maps a gl format into the GrCompressed enum.
+ */
+GrCompression GrGLFormat2Compression(GrGLenum glFormat);
+
+/**
* Returns the data size for the given compressed format
*/
size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height);
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index d281524..1387c31 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -663,7 +663,7 @@
options: options];
} else {
transferBuffer = [fDevice newBufferWithLength: bufferSize
- options: options];
+ options: options];
}
if (nil == transferBuffer) {
return false;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index eec68dd..873ac8b 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1444,73 +1444,58 @@
////////////////////////////////////////////////////////////////////////////////
-bool copy_testing_data(GrVkGpu* gpu, const void* srcData, const GrVkAlloc& alloc,
- size_t bufferOffset, size_t srcRowBytes,
- GrPixelConfig destConfig, size_t dstRowBytes,
- size_t trimRowBytes, int width, int height, const SkColor4f* color) {
- SkASSERT(srcData || color);
+bool copy_src_data(GrVkGpu* gpu, const GrVkAlloc& alloc, VkFormat vkFormat,
+ int width, int height,
+ const void* srcData, size_t srcRowBytes) {
+ SkASSERT(srcData);
- VkDeviceSize size = dstRowBytes * height;
- VkDeviceSize offset = bufferOffset;
- SkASSERT(size + offset <= alloc.fSize);
void* mapPtr = GrVkMemory::MapAlloc(gpu, alloc);
if (!mapPtr) {
return false;
}
- mapPtr = reinterpret_cast<char*>(mapPtr) + offset;
+ mapPtr = reinterpret_cast<char*>(mapPtr);
- if (srcData) {
- SkRectMemcpy(mapPtr, dstRowBytes, srcData, srcRowBytes, trimRowBytes, height);
+ if (GrVkFormatIsCompressed(vkFormat)) {
+ SkASSERT(0 == srcRowBytes);
+ size_t levelSize = GrVkFormatCompressedDataSize(vkFormat, width, height);
+
+ SkASSERT(levelSize <= alloc.fSize);
+ memcpy(mapPtr, srcData, levelSize);
} else {
- if (kRGB_ETC1_GrPixelConfig == destConfig) {
- GrFillInETC1WithColor(width, height, *color, mapPtr);
- } else {
- GrFillBufferWithColor(destConfig, width, height, *color, mapPtr);
+ size_t bytesPerPixel = GrVkBytesPerFormat(vkFormat);
+ const size_t trimRowBytes = width * bytesPerPixel;
+ if (!srcRowBytes) {
+ srcRowBytes = trimRowBytes;
}
+ SkASSERT(trimRowBytes * height <= alloc.fSize);
+
+ SkRectMemcpy(mapPtr, trimRowBytes, srcData, srcRowBytes, trimRowBytes, height);
}
- GrVkMemory::FlushMappedAlloc(gpu, alloc, offset, size);
+
+ GrVkMemory::FlushMappedAlloc(gpu, alloc, 0, alloc.fSize);
GrVkMemory::UnmapAlloc(gpu, alloc);
return true;
}
-static size_t compute_combined_buffer_size(VkFormat format, size_t bpp, int w, int h,
- SkTArray<size_t>* individualMipOffsets,
- uint32_t mipLevels) {
+bool fill_in_with_color(GrVkGpu* gpu, const GrVkAlloc& alloc, VkFormat vkFormat,
+ int baseWidth, int baseHeight,
+ const SkTArray<size_t>& individualMipOffsets,
+ GrPixelConfig config, const SkColor4f& color) {
- size_t combinedBufferSize = w * bpp * h;
- if (GrVkFormatIsCompressed(format)) {
- combinedBufferSize = GrVkFormatCompressedDataSize(format, w, h);
+ GrCompression compression = GrVkFormat2Compression(vkFormat);
+
+ void* mapPtr = GrVkMemory::MapAlloc(gpu, alloc);
+ if (!mapPtr) {
+ return false;
}
- int currentWidth = w;
- int currentHeight = h;
+ // TODO: pass in alloc.fSize and assert we never write past it
+ GrFillInData(compression, config, baseWidth, baseHeight,
+ individualMipOffsets, (char*) mapPtr, color);
- // The Vulkan spec for copying a buffer to an image, requires that the alignment must be at
- // least 4 bytes and a multiple of the bytes per pixel of the image config.
- SkASSERT(bpp == 1 || bpp == 2 || bpp == 3 || bpp == 4 || bpp == 8 || bpp == 16);
- int desiredAlignment = (bpp == 3) ? 12 : (bpp > 4 ? bpp : 4);
-
- for (uint32_t currentMipLevel = 1; currentMipLevel < mipLevels; currentMipLevel++) {
- currentWidth = SkTMax(1, currentWidth / 2);
- currentHeight = SkTMax(1, currentHeight / 2);
-
- size_t trimmedSize;
- if (GrVkFormatIsCompressed(format)) {
- trimmedSize = GrVkFormatCompressedDataSize(format, currentWidth, currentHeight);
- } else {
- trimmedSize = currentWidth * bpp * currentHeight;
- }
- const size_t alignmentDiff = combinedBufferSize % desiredAlignment;
- if (alignmentDiff != 0) {
- combinedBufferSize += desiredAlignment - alignmentDiff;
- }
- SkASSERT((0 == combinedBufferSize % 4) && (0 == combinedBufferSize % bpp));
-
- individualMipOffsets->push_back(combinedBufferSize);
- combinedBufferSize += trimmedSize;
- }
-
- return combinedBufferSize;
+ GrVkMemory::FlushMappedAlloc(gpu, alloc, 0, alloc.fSize);
+ GrVkMemory::UnmapAlloc(gpu, alloc);
+ return true;
}
bool GrVkGpu::createTestingOnlyVkImage(GrPixelConfig config, int w, int h, bool texturable,
@@ -1601,14 +1586,15 @@
err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
SkASSERT(!err);
- size_t bpp = GrVkBytesPerFormat(vkFormat);
+ size_t bytesPerPixel = GrVkBytesPerFormat(vkFormat);
SkASSERT(w && h);
SkTArray<size_t> individualMipOffsets(mipLevels);
- individualMipOffsets.push_back(0);
- size_t combinedBufferSize = compute_combined_buffer_size(vkFormat, bpp, w, h,
- &individualMipOffsets, mipLevels);
+ GrCompression compression = GrVkFormat2Compression(vkFormat);
+
+ size_t combinedBufferSize = GrComputeTightCombinedBufferSize(compression, bytesPerPixel, w, h,
+ &individualMipOffsets, mipLevels);
VkBufferCreateInfo bufInfo;
memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
@@ -1637,41 +1623,26 @@
return false;
}
- int currentWidth = w;
- int currentHeight = h;
- for (uint32_t currentMipLevel = 0; currentMipLevel < mipLevels; currentMipLevel++) {
- SkASSERT(0 == currentMipLevel || !srcData);
- size_t bufferOffset = individualMipOffsets[currentMipLevel];
- bool result;
- if (GrVkFormatIsCompressed(vkFormat)) {
- size_t levelSize = GrVkFormatCompressedDataSize(vkFormat, currentWidth, currentHeight);
- size_t currentRowBytes = levelSize / currentHeight;
- result = copy_testing_data(this, srcData, bufferAlloc, bufferOffset, currentRowBytes,
- config, currentRowBytes, currentRowBytes,
- currentWidth, currentHeight, &color);
- } else {
- const size_t trimRowBytes = bpp * currentWidth;
- if (!srcRowBytes) {
- srcRowBytes = trimRowBytes;
- }
+ bool result;
+ if (!srcData) {
+ result = fill_in_with_color(this, bufferAlloc, vkFormat, w, h, individualMipOffsets,
+ config, color);
+ } else {
+ SkASSERT(1 == mipLevels);
- size_t currentRowBytes = bpp * currentWidth;
- result = copy_testing_data(this, srcData, bufferAlloc, bufferOffset, srcRowBytes,
- config, currentRowBytes, trimRowBytes,
- currentWidth, currentHeight, &color);
- }
- if (!result) {
- GrVkImage::DestroyImageInfo(this, info);
- GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
- VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
- VK_CALL(EndCommandBuffer(cmdBuffer));
- VK_CALL(FreeCommandBuffers(fDevice, fCmdPool->vkCommandPool(), 1, &cmdBuffer));
- return false;
- }
- currentWidth = SkTMax(1, currentWidth / 2);
- currentHeight = SkTMax(1, currentHeight / 2);
+ result = copy_src_data(this, bufferAlloc, vkFormat, w, h, srcData, srcRowBytes);
}
+ if (!result) {
+ GrVkImage::DestroyImageInfo(this, info);
+ GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
+ VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+ VK_CALL(EndCommandBuffer(cmdBuffer));
+ VK_CALL(FreeCommandBuffers(fDevice, fCmdPool->vkCommandPool(), 1, &cmdBuffer));
+ return false;
+ }
+
+
// Set image layout and add barrier
VkImageMemoryBarrier barrier;
memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
@@ -1694,8 +1665,8 @@
SkTArray<VkBufferImageCopy> regions(mipLevels);
- currentWidth = w;
- currentHeight = h;
+ int currentWidth = w;
+ int currentHeight = h;
for (uint32_t currentMipLevel = 0; currentMipLevel < mipLevels; currentMipLevel++) {
// Submit copy command
VkBufferImageCopy& region = regions.push_back();
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 8787e50..338cc3b 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -304,7 +304,7 @@
return 16;
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
- return 8;
+ return 0;
// Experimental (for P016 and P010)
case VK_FORMAT_R16_UNORM:
@@ -332,6 +332,17 @@
return false;
}
+GrCompression GrVkFormat2Compression(VkFormat vkFormat) {
+ switch (vkFormat) {
+ case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
+ return GrCompression::kETC1;
+ default:
+ return GrCompression::kNone;
+ }
+ SK_ABORT("Invalid format");
+ return GrCompression::kNone;
+}
+
size_t GrVkFormatCompressedDataSize(VkFormat vkFormat, int width, int height) {
SkASSERT(GrVkFormatIsCompressed(vkFormat));
diff --git a/src/gpu/vk/GrVkUtil.h b/src/gpu/vk/GrVkUtil.h
index 35c13a7..06e052e 100644
--- a/src/gpu/vk/GrVkUtil.h
+++ b/src/gpu/vk/GrVkUtil.h
@@ -12,6 +12,7 @@
#include "include/gpu/vk/GrVkTypes.h"
#include "include/private/GrColor.h"
#include "include/private/SkMacros.h"
+#include "src/gpu/GrDataUtils.h"
#include "src/gpu/vk/GrVkInterface.h"
#include "src/sksl/ir/SkSLProgram.h"
@@ -71,4 +72,9 @@
*/
size_t GrVkFormatCompressedDataSize(VkFormat, int width, int height);
+/**
+ * Maps a vk format into the GrCompressed enum.
+ */
+GrCompression GrVkFormat2Compression(VkFormat);
+
#endif