Make sure we have a valid command buffer throughout vulkan.
This is a speculative fix for linked chromium bug
Bug: chromium:1096535
Change-Id: Ifa2f3bb116695d0163b70e721e2da17279a68edb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/300708
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 3b7787f..8f9148c 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -327,7 +327,9 @@
bool GrVkGpu::submitCommandBuffer(SyncQueue sync) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
- SkASSERT(this->currentCommandBuffer());
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
SkASSERT(!fCachedOpsRenderPass || !fCachedOpsRenderPass->isActive());
if (!this->currentCommandBuffer()->hasWork() && kForce_SyncQueue != sync &&
@@ -478,6 +480,9 @@
GrColorType surfaceColorType, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t bufferOffset,
size_t rowBytes) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
if (surfaceColorType != bufferColorType) {
return false;
}
@@ -542,6 +547,9 @@
bool GrVkGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
GrColorType surfaceColorType, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
SkASSERT(surface);
SkASSERT(transferBuffer);
if (fProtectedContext == GrProtected::kYes) {
@@ -603,6 +611,10 @@
void GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
+
SkASSERT(dst);
SkASSERT(src && src->numSamples() > 1 && src->msaaImage());
@@ -755,6 +767,10 @@
bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, int left, int top, int width, int height,
GrColorType dataColorType, const GrMipLevel texels[],
int mipLevelCount) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
+
SkASSERT(!tex->isLinearTiled());
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
SkASSERT(1 == mipLevelCount ||
@@ -943,6 +959,9 @@
SkImage::CompressionType compression, VkFormat vkFormat,
SkISize dimensions, GrMipMapped mipMapped,
const void* data, size_t dataSize) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
SkASSERT(data);
SkASSERT(!uploadTexture->isLinearTiled());
// For now the assumption is that our rect is the entire texture.
@@ -1058,6 +1077,9 @@
}
if (levelClearMask) {
+ if (!this->currentCommandBuffer()) {
+ return nullptr;
+ }
SkSTArray<1, VkImageSubresourceRange> ranges;
bool inRange = false;
for (uint32_t i = 0; i < tex->mipLevels(); ++i) {
@@ -1146,6 +1168,9 @@
void GrVkGpu::copyBuffer(GrVkBuffer* srcBuffer, GrVkBuffer* dstBuffer, VkDeviceSize srcOffset,
VkDeviceSize dstOffset, VkDeviceSize size) {
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
VkBufferCopy copyRegion;
copyRegion.srcOffset = srcOffset;
copyRegion.dstOffset = dstOffset;
@@ -1155,6 +1180,9 @@
bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src,
VkDeviceSize offset, VkDeviceSize size) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
// Update the buffer
this->currentCommandBuffer()->updateBuffer(this, buffer, offset, size, src);
@@ -1409,6 +1437,9 @@
}
bool GrVkGpu::onRegenerateMipMapLevels(GrTexture* tex) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
auto* vkTex = static_cast<GrVkTexture*>(tex);
// don't do anything for linearly tiled textures (can't have mipmaps)
if (vkTex->isLinearTiled()) {
@@ -1990,7 +2021,9 @@
VkPipelineStageFlags dstStageMask,
bool byRegion,
VkBufferMemoryBarrier* barrier) const {
- SkASSERT(this->currentCommandBuffer());
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
SkASSERT(resource);
this->currentCommandBuffer()->pipelineBarrier(this,
resource,
@@ -2083,6 +2116,10 @@
void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, GrSurface* src, GrVkImage* dstImage,
GrVkImage* srcImage, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
+
#ifdef SK_DEBUG
int dstSampleCnt = get_surface_sample_cnt(dst);
int srcSampleCnt = get_surface_sample_cnt(src);
@@ -2138,6 +2175,10 @@
void GrVkGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, GrVkImage* dstImage,
GrVkImage* srcImage, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
+
#ifdef SK_DEBUG
int dstSampleCnt = get_surface_sample_cnt(dst);
int srcSampleCnt = get_surface_sample_cnt(src);
@@ -2285,6 +2326,10 @@
return false;
}
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
+
GrVkImage* image = nullptr;
GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarget());
if (rt) {
@@ -2473,6 +2518,9 @@
const VkClearValue* colorClear,
GrVkRenderTarget* target, GrSurfaceOrigin origin,
const SkIRect& bounds, bool forSecondaryCB) {
+ if (!this->currentCommandBuffer()) {
+ return false;
+ }
SkASSERT (!target->wrapsSecondaryCommandBuffer());
auto nativeBounds = GrNativeRect::MakeRelativeTo(origin, target->height(), bounds);
@@ -2508,11 +2556,16 @@
void GrVkGpu::endRenderPass(GrRenderTarget* target, GrSurfaceOrigin origin,
const SkIRect& bounds) {
+ // We had a command buffer when we started the render pass, we should have one now as well.
+ SkASSERT(this->currentCommandBuffer());
this->currentCommandBuffer()->endRenderPass(this);
this->didWriteToSurface(target, origin, &bounds);
}
void GrVkGpu::submitSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> buffer) {
+ if (!this->currentCommandBuffer()) {
+ return;
+ }
this->currentCommandBuffer()->executeCommands(this, std::move(buffer));
}
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index d80b8c5..00f54b9 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -174,6 +174,9 @@
if (fCurrentSecondaryCommandBuffer) {
return fCurrentSecondaryCommandBuffer.get();
}
+ // We checked this when we setup the GrVkOpsRenderPass and it should not have changed while we
+ // are still using this object.
+ SkASSERT(fGpu->currentCommandBuffer());
return fGpu->currentCommandBuffer();
}
@@ -214,6 +217,13 @@
fIsActive = true;
#endif
+ // We check to make sure the GrVkGpu has a valid current command buffer instead of each time we
+ // access it. If the command buffer is valid here should be valid throughout the use of the
+ // render pass since nothing should trigger a submit while this render pass is active.
+ if (!fGpu->currentCommandBuffer()) {
+ return false;
+ }
+
this->INHERITED::set(rt, origin);
for (int i = 0; i < sampledProxies.count(); ++i) {