aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-10-09 15:06:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-10 16:45:43 +0000
commit834f12076f703c114173486de6470412d92f6506 (patch)
tree0cdbc645742e740f3934a96f2cb8b80e6fb62c6d /src/gpu
parentc5b94988915920ed359eecec34d4fbd6bdc0a3fd (diff)
Set correct mip map status on GrTexture since we no longer require all mip data
Bug: skia: Change-Id: I5074028f307187eef3201523cbd1ddc7d9bf9013 Reviewed-on: https://skia-review.googlesource.com/54102 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrTexture.cpp19
-rw-r--r--src/gpu/GrTexturePriv.h8
-rw-r--r--src/gpu/gl/GrGLGpu.cpp29
-rw-r--r--src/gpu/gl/GrGLGpu.h6
-rw-r--r--src/gpu/gl/GrGLTexture.cpp13
-rw-r--r--src/gpu/gl/GrGLTexture.h5
-rw-r--r--src/gpu/gl/GrGLTextureRenderTarget.cpp12
-rw-r--r--src/gpu/gl/GrGLTextureRenderTarget.h6
-rw-r--r--src/gpu/mock/GrMockTexture.h2
-rw-r--r--src/gpu/mtl/GrMtlGpu.mm2
-rw-r--r--src/gpu/mtl/GrMtlTexture.h6
-rw-r--r--src/gpu/mtl/GrMtlTexture.mm11
-rw-r--r--src/gpu/vk/GrVkGpu.cpp17
-rw-r--r--src/gpu/vk/GrVkTexture.cpp18
-rw-r--r--src/gpu/vk/GrVkTexture.h12
-rw-r--r--src/gpu/vk/GrVkTextureRenderTarget.cpp32
-rw-r--r--src/gpu/vk/GrVkTextureRenderTarget.h12
17 files changed, 140 insertions, 70 deletions
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 361fd1a5f7..c134c64c29 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -19,12 +19,12 @@
void GrTexture::dirtyMipMaps(bool mipMapsDirty) {
if (mipMapsDirty) {
- if (kValid_MipMapsStatus == fMipMapsStatus) {
- fMipMapsStatus = kAllocated_MipMapsStatus;
+ if (kInvalid_MipMapsStatus == fMipMapsStatus || kClean_MipMapsStatus == fMipMapsStatus) {
+ fMipMapsStatus = kDirty_MipMapsStatus;
}
} else {
const bool sizeChanged = kNotAllocated_MipMapsStatus == fMipMapsStatus;
- fMipMapsStatus = kValid_MipMapsStatus;
+ fMipMapsStatus = kClean_MipMapsStatus;
if (sizeChanged) {
// This must not be called until after changing fMipMapsStatus.
this->didChangeGpuMemorySize();
@@ -41,14 +41,21 @@ size_t GrTexture::onGpuMemorySize() const {
/////////////////////////////////////////////////////////////////////////////
GrTexture::GrTexture(GrGpu* gpu, const GrSurfaceDesc& desc, GrSLType samplerType,
- GrSamplerState::Filter highestFilterMode, bool wasMipMapDataProvided)
+ GrSamplerState::Filter highestFilterMode,
+ bool mipsAllocated, bool wasFullMipMapDataProvided)
: INHERITED(gpu, desc)
, fSamplerType(samplerType)
, fHighestFilterMode(highestFilterMode)
// Mip color mode is explicitly set after creation via GrTexturePriv
, fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) {
- if (wasMipMapDataProvided) {
- fMipMapsStatus = kValid_MipMapsStatus;
+ if (mipsAllocated) {
+ if (wasFullMipMapDataProvided) {
+ fMipMapsStatus = kClean_MipMapsStatus;
+ } else {
+ // Currently we should only hit this case when none of the mips were uploaded including
+ // the base. Thus we set this to invalid.
+ fMipMapsStatus = kInvalid_MipMapsStatus;
+ }
fMaxMipMapLevel = SkMipMap::ComputeLevelCount(this->width(), this->height());
} else {
fMipMapsStatus = kNotAllocated_MipMapsStatus;
diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h
index a470b3bee6..3986c96746 100644
--- a/src/gpu/GrTexturePriv.h
+++ b/src/gpu/GrTexturePriv.h
@@ -22,13 +22,19 @@ public:
}
bool mipMapsAreDirty() const {
- return GrTexture::kValid_MipMapsStatus != fTexture->fMipMapsStatus;
+ return GrTexture::kClean_MipMapsStatus != fTexture->fMipMapsStatus;
}
bool hasMipMaps() const {
return GrTexture::kNotAllocated_MipMapsStatus != fTexture->fMipMapsStatus;
}
+ // Once we no longer support allocating mip levels after creation, we can also require that mips
+ // have been allocated to the valid check.
+ bool mipMapsAreValid() const {
+ return GrTexture::kInvalid_MipMapsStatus != fTexture->fMipMapsStatus;
+ }
+
void setMaxMipMapLevel(int maxMipMapLevel) const {
fTexture->fMaxMipMapLevel = maxMipMapLevel;
}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 159cec721f..bef1f1919f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1009,7 +1009,8 @@ void GrGLGpu::unbindCpuToGpuXferBuffer() {
bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType,
int left, int top, int width, int height, GrPixelConfig dataConfig,
- const GrMipLevel texels[], int mipLevelCount) {
+ const GrMipLevel texels[], int mipLevelCount,
+ bool* wasFullMipMapDataProvided) {
SkASSERT(this->caps()->isConfigTexturable(texConfig));
SkDEBUGCODE(
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
@@ -1075,6 +1076,11 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
// in case we need a temporary, trimmed copy of the src pixels
SkAutoSMalloc<128 * 128> tempStorage;
+ if (wasFullMipMapDataProvided) {
+ // Make sure this is initialized to true
+ *wasFullMipMapDataProvided = true;
+ }
+
// find the combined size of all the mip levels and the relative offset of
// each into the collective buffer
size_t combinedBufferSize = 0;
@@ -1088,6 +1094,9 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
individualMipOffsets.push_back(combinedBufferSize);
combinedBufferSize += trimmedSize;
} else {
+ if (wasFullMipMapDataProvided) {
+ *wasFullMipMapDataProvided = false;
+ }
individualMipOffsets.push_back(0);
}
@@ -1407,15 +1416,16 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GrGLTexture::IDDesc idDesc;
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
+ bool wasFullMipMapDataProvided = true;
GrGLTexture::TexParams initialTexParams;
if (!this->createTextureImpl(desc, &idDesc.fInfo, isRenderTarget, &initialTexParams,
- texels, mipLevelCount)) {
+ texels, mipLevelCount, &wasFullMipMapDataProvided)) {
return return_null_texture();
}
- bool wasMipMapDataProvided = false;
+ bool mipsAllocated = false;
if (mipLevelCount > 1) {
- wasMipMapDataProvided = true;
+ mipsAllocated = true;
}
sk_sp<GrGLTexture> tex;
@@ -1429,10 +1439,11 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
return return_null_texture();
}
tex = sk_make_sp<GrGLTextureRenderTarget>(this, budgeted, desc, idDesc, rtIDDesc,
- wasMipMapDataProvided);
+ mipsAllocated, wasFullMipMapDataProvided);
tex->baseLevelWasBoundToFBO();
} else {
- tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, wasMipMapDataProvided);
+ tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc,
+ mipsAllocated, wasFullMipMapDataProvided);
}
tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
#ifdef TRACE_TEXTURE_CREATION
@@ -1603,7 +1614,8 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
- const GrMipLevel texels[], int mipLevelCount) {
+ const GrMipLevel texels[], int mipLevelCount,
+ bool* wasFullMipMapDataProvided) {
info->fID = 0;
info->fTarget = GR_GL_TEXTURE_2D;
GL_CALL(GenTextures(1, &(info->fID)));
@@ -3165,6 +3177,9 @@ void GrGLGpu::generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs
return;
}
+ // Make sure we at least have some base layer to make mips from
+ SkASSERT(texture->texturePriv().mipMapsAreValid());
+
// If we created a rt/tex and rendered to it without using a texture and now we're texturing
// from the rt it will still be the last bound texture, but it needs resolving.
GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 000b56581d..20758c382c 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -224,7 +224,8 @@ private:
// The texture parameters are cached in |initialTexParams|.
bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
- const GrMipLevel texels[], int mipLevelCount);
+ const GrMipLevel texels[], int mipLevelCount,
+ bool* wasFullMipMapDataProvided);
bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerState&,
GrTextureProducer::CopyParams*,
@@ -391,7 +392,8 @@ private:
bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType, int left,
int top, int width, int height, GrPixelConfig dataConfig,
- const GrMipLevel texels[], int mipLevelCount);
+ const GrMipLevel texels[], int mipLevelCount,
+ bool* wasFullMipMapDataProvided = nullptr);
bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
GrGLRenderTarget::IDDesc*);
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 0d71321ab0..789c0b756e 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -52,18 +52,19 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc&
const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
- highest_filter_mode(idDesc, desc.fConfig), false) {
+ highest_filter_mode(idDesc, desc.fConfig), false, false) {
this->init(desc, idDesc);
this->registerWithCache(budgeted);
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
const IDDesc& idDesc,
- bool wasMipMapDataProvided)
+ bool mipsAllocated,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
highest_filter_mode(idDesc, desc.fConfig),
- wasMipMapDataProvided) {
+ mipsAllocated, wasFullMipMapDataProvided) {
this->init(desc, idDesc);
this->registerWithCache(budgeted);
}
@@ -71,17 +72,17 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc&
GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc, const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
- highest_filter_mode(idDesc, desc.fConfig), false) {
+ highest_filter_mode(idDesc, desc.fConfig), false, false) {
this->init(desc, idDesc);
this->registerWithCacheWrapped();
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
- bool wasMipMapDataProvided)
+ bool mipsAllocated, bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
highest_filter_mode(idDesc, desc.fConfig),
- wasMipMapDataProvided) {
+ mipsAllocated, wasFullMipMapDataProvided) {
this->init(desc, idDesc);
}
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 85ada01c87..f2dc739f2d 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -34,7 +34,7 @@ public:
};
GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&);
GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&,
- bool wasMipMapDataProvided);
+ bool mipsAllocated, bool wasFullMipMapDataProvided);
~GrGLTexture() override {
// check that invokeReleaseProc has been called (if needed)
@@ -73,7 +73,8 @@ public:
protected:
// Constructor for subclasses.
- GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, bool wasMipMapDataProvided);
+ GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&,
+ bool mipsAllocated, bool wasMipMapDataProvided);
enum Wrapped { kWrapped };
// Constructor for instances wrapping backend objects.
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp
index ef401cdd06..b60d3c94ef 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.cpp
+++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp
@@ -17,9 +17,10 @@ GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc,
- bool wasMipMapDataProvided)
+ bool mipsAllocated,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
- , GrGLTexture(gpu, desc, texIDDesc, wasMipMapDataProvided)
+ , GrGLTexture(gpu, desc, texIDDesc, mipsAllocated, wasFullMipMapDataProvided)
, GrGLRenderTarget(gpu, desc, rtIDDesc) {
this->registerWithCache(budgeted);
}
@@ -27,10 +28,9 @@ GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
- const GrGLRenderTarget::IDDesc& rtIDDesc,
- bool wasMipMapDataProvided)
+ const GrGLRenderTarget::IDDesc& rtIDDesc)
: GrSurface(gpu, desc)
- , GrGLTexture(gpu, desc, texIDDesc, wasMipMapDataProvided)
+ , GrGLTexture(gpu, desc, texIDDesc, false, false)
, GrGLRenderTarget(gpu, desc, rtIDDesc) {
this->registerWithCacheWrapped();
}
@@ -75,7 +75,7 @@ sk_sp<GrGLTextureRenderTarget> GrGLTextureRenderTarget::MakeWrapped(
const GrGLTexture::IDDesc& texIDDesc, const GrGLRenderTarget::IDDesc& rtIDDesc)
{
return sk_sp<GrGLTextureRenderTarget>(
- new GrGLTextureRenderTarget(gpu, desc, texIDDesc, rtIDDesc, false));
+ new GrGLTextureRenderTarget(gpu, desc, texIDDesc, rtIDDesc));
}
size_t GrGLTextureRenderTarget::onGpuMemorySize() const {
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h
index e104e85b3f..2242933e0c 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.h
+++ b/src/gpu/gl/GrGLTextureRenderTarget.h
@@ -29,7 +29,8 @@ public:
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc,
- bool wasMipMapDataProvided);
+ bool mipsAllocated,
+ bool wasFullMipMapDataProvided);
bool canAttemptStencilAttachment() const override;
@@ -54,8 +55,7 @@ private:
GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
- const GrGLRenderTarget::IDDesc& rtIDDesc,
- bool wasMipMapDataProvided);
+ const GrGLRenderTarget::IDDesc& rtIDDesc);
size_t onGpuMemorySize() const override;
};
diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h
index c5c21025e8..21f0eeca1a 100644
--- a/src/gpu/mock/GrMockTexture.h
+++ b/src/gpu/mock/GrMockTexture.h
@@ -40,7 +40,7 @@ protected:
const GrMockTextureInfo& info)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, kITexture2DSampler_GrSLType, GrSamplerState::Filter::kMipMap,
- hasMipLevels)
+ hasMipLevels, hasMipLevels)
, fInfo(info)
, fReleaseProc(nullptr)
, fReleaseCtx(nullptr) {}
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index a830959bdd..47035f9e0e 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -128,7 +128,7 @@ sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
desc, mipLevels);
#endif
} else {
- tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, mipLevels);
+ tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, mipLevels, false);
}
if (!tex) {
diff --git a/src/gpu/mtl/GrMtlTexture.h b/src/gpu/mtl/GrMtlTexture.h
index 2d3580ef71..0e5e30c9ac 100644
--- a/src/gpu/mtl/GrMtlTexture.h
+++ b/src/gpu/mtl/GrMtlTexture.h
@@ -17,7 +17,8 @@ class GrMtlGpu;
class GrMtlTexture : public GrTexture {
public:
static sk_sp<GrMtlTexture> CreateNewTexture(GrMtlGpu*, SkBudgeted budgeted,
- const GrSurfaceDesc&, int mipLevels);
+ const GrSurfaceDesc&, int mipLevels,
+ bool wasFullMipMapDataProvided);
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&,
GrWrapOwnership);
@@ -54,7 +55,8 @@ protected:
private:
enum Wrapped { kWrapped };
- GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>, bool isMipMapped);
+ GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>, bool isMipMapped,
+ bool wasFullMipMapDataProvided);
// GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, GrMtlImage::Wrapped wrapped);
id<MTLTexture> fTexture;
diff --git a/src/gpu/mtl/GrMtlTexture.mm b/src/gpu/mtl/GrMtlTexture.mm
index cdc9b0c195..d66f2ba6be 100644
--- a/src/gpu/mtl/GrMtlTexture.mm
+++ b/src/gpu/mtl/GrMtlTexture.mm
@@ -12,7 +12,8 @@
#include "GrTexturePriv.h"
sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted,
- const GrSurfaceDesc& desc, int mipLevels) {
+ const GrSurfaceDesc& desc, int mipLevels,
+ bool wasFullMipMapDataProvided) {
MTLPixelFormat format;
if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
return nullptr;
@@ -40,7 +41,8 @@ sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted bud
id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:descriptor];
- return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipLevels > 1));
+ return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipLevels > 1,
+ wasFullMipMapDataProvided));
}
// This method parallels GrTextureProxy::highestFilterMode
@@ -56,10 +58,11 @@ GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
id<MTLTexture> texture,
- bool isMipMapped)
+ bool isMipMapped,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
- isMipMapped)
+ isMipMapped, wasFullMipMapDataProvided)
, fTexture(texture) {
}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index e9adb4db67..b756bd5354 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -818,12 +818,22 @@ sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
imageDesc.fUsageFlags = usageFlags;
imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ bool fullMipMapDataProvided = true;
+ for (int i = 0; i < mipLevelCount; ++i) {
+ if (!texels[i].fPixels) {
+ fullMipMapDataProvided = false;
+ break;
+ }
+ }
+
sk_sp<GrVkTexture> tex;
if (renderTarget) {
tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc,
- imageDesc);
+ imageDesc,
+ fullMipMapDataProvided);
} else {
- tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc);
+ tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc,
+ fullMipMapDataProvided);
}
if (!tex) {
@@ -989,6 +999,9 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex, GrSurfaceOrigin texOrigin) {
return;
}
+ // Make sure we at least have some base layer to make mips from
+ SkASSERT(tex->texturePriv().mipMapsAreValid());
+
// determine if we can blit to and from this format
const GrVkCaps& caps = this->vkCaps();
if (!caps.configCanBeDstofBlit(tex->config(), false) ||
diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp
index 1049e53e7b..7d8f017fec 100644
--- a/src/gpu/vk/GrVkTexture.cpp
+++ b/src/gpu/vk/GrVkTexture.cpp
@@ -31,11 +31,12 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
- const GrVkImageView* view)
+ const GrVkImageView* view,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, GrVkImage(info, GrBackendObjectOwnership::kOwned)
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
- info.fLevelCount > 1)
+ info.fLevelCount > 1, wasFullMipMapDataProvided)
, fTextureView(view)
, fLinearTextureView(nullptr) {
this->registerWithCache(budgeted);
@@ -50,7 +51,7 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
- info.fLevelCount > 1)
+ info.fLevelCount > 1, false)
, fTextureView(view)
, fLinearTextureView(nullptr) {
this->registerWithCacheWrapped();
@@ -61,18 +62,20 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
const GrVkImageView* view,
- GrBackendObjectOwnership ownership)
+ GrBackendObjectOwnership ownership,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
- info.fLevelCount > 1)
+ info.fLevelCount > 1, wasFullMipMapDataProvided)
, fTextureView(view)
, fLinearTextureView(nullptr) {
}
sk_sp<GrVkTexture> GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budgeted,
const GrSurfaceDesc& desc,
- const GrVkImage::ImageDesc& imageDesc) {
+ const GrVkImage::ImageDesc& imageDesc,
+ bool fullMipMapDataProvided) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
GrVkImageInfo info;
@@ -88,7 +91,8 @@ sk_sp<GrVkTexture> GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budget
return nullptr;
}
- return sk_sp<GrVkTexture>(new GrVkTexture(gpu, budgeted, desc, info, imageView));
+ return sk_sp<GrVkTexture>(new GrVkTexture(gpu, budgeted, desc, info, imageView,
+ fullMipMapDataProvided));
}
sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index 40d778f74c..fde7d72aa1 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -17,8 +17,11 @@ struct GrVkImageInfo;
class GrVkTexture : public GrTexture, public virtual GrVkImage {
public:
- static sk_sp<GrVkTexture> CreateNewTexture(GrVkGpu*, SkBudgeted budgeted, const GrSurfaceDesc&,
- const GrVkImage::ImageDesc&);
+ static sk_sp<GrVkTexture> CreateNewTexture(GrVkGpu*,
+ SkBudgeted budgeted,
+ const GrSurfaceDesc&,
+ const GrVkImage::ImageDesc&,
+ bool wasFullMipMapDataProvided);
static sk_sp<GrVkTexture> MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&,
GrWrapOwnership, const GrVkImageInfo*);
@@ -42,7 +45,7 @@ public:
protected:
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, const GrVkImageView*,
- GrBackendObjectOwnership);
+ GrBackendObjectOwnership, bool wasFullMipMapDataProvided);
GrVkGpu* getVkGpu() const;
@@ -52,7 +55,8 @@ protected:
private:
enum Wrapped { kWrapped };
GrVkTexture(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&,
- const GrVkImageInfo&, const GrVkImageView* imageView);
+ const GrVkImageInfo&, const GrVkImageView* imageView,
+ bool wasFullMipMapDataProvided);
GrVkTexture(GrVkGpu*, Wrapped, const GrSurfaceDesc&,
const GrVkImageInfo&, const GrVkImageView* imageView, GrBackendObjectOwnership);
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index 6b7bc6bb02..4a9859b879 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -26,10 +26,11 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
const GrVkImageInfo& msaaInfo,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
- GrBackendObjectOwnership ownership)
+ GrBackendObjectOwnership ownership,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
- , GrVkTexture(gpu, desc, info, texView, ownership)
+ , GrVkTexture(gpu, desc, info, texView, ownership, wasFullMipMapDataProvided)
, GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView,
resolveAttachmentView, GrBackendObjectOwnership::kOwned) {
this->registerWithCache(budgeted);
@@ -41,10 +42,11 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
const GrVkImageInfo& info,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView,
- GrBackendObjectOwnership ownership)
+ GrBackendObjectOwnership ownership,
+ bool wasFullMipMapDataProvided)
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
- , GrVkTexture(gpu, desc, info, texView, ownership)
+ , GrVkTexture(gpu, desc, info, texView, ownership, wasFullMipMapDataProvided)
, GrVkRenderTarget(gpu, desc, info, colorAttachmentView, GrBackendObjectOwnership::kOwned) {
this->registerWithCache(budgeted);
}
@@ -59,7 +61,7 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
GrBackendObjectOwnership ownership)
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
- , GrVkTexture(gpu, desc, info, texView, ownership)
+ , GrVkTexture(gpu, desc, info, texView, ownership, false)
, GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView,
resolveAttachmentView, ownership) {
this->registerWithCacheWrapped();
@@ -73,7 +75,7 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
GrBackendObjectOwnership ownership)
: GrSurface(gpu, desc)
, GrVkImage(info, ownership)
- , GrVkTexture(gpu, desc, info, texView, ownership)
+ , GrVkTexture(gpu, desc, info, texView, ownership, false)
, GrVkRenderTarget(gpu, desc, info, colorAttachmentView, ownership) {
this->registerWithCacheWrapped();
}
@@ -84,7 +86,9 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
const GrVkImageInfo& info,
SkBudgeted budgeted,
GrBackendObjectOwnership ownership,
- bool isWrapped) {
+ bool isWrapped,
+ bool wasFullMipMapDataProvided) {
+ SkASSERT(!wasFullMipMapDataProvided || !isWrapped);
VkImage image = info.fImage;
// Create the texture ImageView
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
@@ -156,7 +160,8 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
gpu, budgeted, desc,
info, imageView, msInfo,
colorAttachmentView,
- resolveAttachmentView, ownership));
+ resolveAttachmentView, ownership,
+ wasFullMipMapDataProvided));
} else {
texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
gpu, desc,
@@ -169,7 +174,8 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
gpu, budgeted, desc,
info, imageView,
- colorAttachmentView, ownership));
+ colorAttachmentView, ownership,
+ wasFullMipMapDataProvided));
} else {
texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
gpu, desc,
@@ -184,7 +190,8 @@ sk_sp<GrVkTextureRenderTarget>
GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
- const GrVkImage::ImageDesc& imageDesc) {
+ const GrVkImage::ImageDesc& imageDesc,
+ bool wasFullMipMapDataProvided) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
@@ -194,7 +201,8 @@ GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
}
sk_sp<GrVkTextureRenderTarget> trt = Make(gpu, desc, info, budgeted,
- GrBackendObjectOwnership::kOwned, false);
+ GrBackendObjectOwnership::kOwned, false,
+ wasFullMipMapDataProvided);
if (!trt) {
GrVkImage::DestroyImageInfo(gpu, &info);
}
@@ -214,7 +222,7 @@ GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu,
GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
- return Make(gpu, desc, *info, SkBudgeted::kNo, ownership, true);
+ return Make(gpu, desc, *info, SkBudgeted::kNo, ownership, true, false);
}
bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) {
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index 6ec5250f46..056be2ee86 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -27,7 +27,8 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget {
public:
static sk_sp<GrVkTextureRenderTarget> CreateNewTextureRenderTarget(GrVkGpu*, SkBudgeted,
const GrSurfaceDesc&,
- const GrVkImage::ImageDesc&);
+ const GrVkImage::ImageDesc&,
+ bool fullMipMapDataProvided);
static sk_sp<GrVkTextureRenderTarget> MakeWrappedTextureRenderTarget(GrVkGpu*,
const GrSurfaceDesc&,
@@ -56,7 +57,8 @@ private:
const GrVkImageInfo& msaaInfo,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
- GrBackendObjectOwnership);
+ GrBackendObjectOwnership,
+ bool wasFullMipMapDataProvided);
GrVkTextureRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
@@ -64,7 +66,8 @@ private:
const GrVkImageInfo& info,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView,
- GrBackendObjectOwnership);
+ GrBackendObjectOwnership,
+ bool wasFullMipMapDataProvided);
GrVkTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
@@ -87,7 +90,8 @@ private:
const GrVkImageInfo&,
SkBudgeted budgeted,
GrBackendObjectOwnership,
- bool isWrapped);
+ bool isWrapped,
+ bool wasFullMipMapDataProvided);
// GrGLRenderTarget accounts for the texture's memory and any MSAA renderbuffer's memory.
size_t onGpuMemorySize() const override;