Add optional param to setBackendTextureState to return previous state.
Bug: skia:10742 Change-Id: I334e7896d0a1509eb666c46d5731d2573a5c1aba Reviewed-on: https://skia-review.googlesource.com/c/skia/+/318698 Reviewed-by: Austin Eng <enga@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
7b97b3cb2b
commit
1d3c8c1a8b
@ -9,6 +9,10 @@ Milestone 87
|
||||
|
||||
* <insert new release notes here>
|
||||
|
||||
* Add new optional parameter to GrContext::setBackend[Texture/RenderTarget]State which can
|
||||
be used to return the previous GrBackendSurfaceMutableState before the requested change.
|
||||
https://review.skia.org/318698
|
||||
|
||||
* New optimized clip stack for GPU backends. Enabled by default but old behavior based on
|
||||
SkClipStack can be restored by defining SK_DISABLE_NEW_GR_CLIP_STACK when building. It is not
|
||||
compatible with SK_SUPPORT_DEPRECATED_CLIPOPS and we are targeting the removal of support for
|
||||
|
@ -38,6 +38,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/GrAutoLocaleSetter.h",
|
||||
"$_src/gpu/GrBackendSemaphore.cpp",
|
||||
"$_src/gpu/GrBackendSurface.cpp",
|
||||
"$_src/gpu/GrBackendSurfaceMutableState.cpp",
|
||||
"$_src/gpu/GrBackendSurfaceMutableStateImpl.h",
|
||||
"$_src/gpu/GrBackendTextureImageGenerator.cpp",
|
||||
"$_src/gpu/GrBackendTextureImageGenerator.h",
|
||||
|
@ -24,35 +24,59 @@
|
||||
*
|
||||
* Vulkan: VkImageLayout and QueueFamilyIndex
|
||||
*/
|
||||
class GrBackendSurfaceMutableState {
|
||||
class SK_API GrBackendSurfaceMutableState {
|
||||
public:
|
||||
GrBackendSurfaceMutableState() {}
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
GrBackendSurfaceMutableState(VkImageLayout layout, uint32_t queueFamilyIndex)
|
||||
: fVkState(layout, queueFamilyIndex)
|
||||
, fBackend(GrBackend::kVulkan) {}
|
||||
, fBackend(GrBackend::kVulkan)
|
||||
, fIsValid(true) {}
|
||||
#endif
|
||||
|
||||
GrBackendSurfaceMutableState& operator=(const GrBackendSurfaceMutableState& that) {
|
||||
switch (fBackend) {
|
||||
case GrBackend::kVulkan:
|
||||
GrBackendSurfaceMutableState(const GrBackendSurfaceMutableState& that);
|
||||
GrBackendSurfaceMutableState& operator=(const GrBackendSurfaceMutableState& that);
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
SkASSERT(that.fBackend == GrBackend::kVulkan);
|
||||
fVkState = that.fVkState;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)that;
|
||||
SkUNREACHABLE;
|
||||
// If this class is not Vulkan backed it will return value of VK_IMAGE_LAYOUT_UNDEFINED.
|
||||
// Otherwise it will return the VkImageLayout.
|
||||
VkImageLayout getVkImageLayout() const {
|
||||
if (this->isValid() && fBackend != GrBackendApi::kVulkan) {
|
||||
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
fBackend = that.fBackend;
|
||||
return *this;
|
||||
return fVkState.getImageLayout();
|
||||
}
|
||||
|
||||
// If this class is not Vulkan backed it will return value of VK_QUEUE_FAMILY_IGNORED.
|
||||
// Otherwise it will return the VkImageLayout.
|
||||
uint32_t getQueueFamilyIndex() const {
|
||||
if (this->isValid() && fBackend != GrBackendApi::kVulkan) {
|
||||
return VK_QUEUE_FAMILY_IGNORED;
|
||||
}
|
||||
return fVkState.getQueueFamilyIndex();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns true if the backend mutable state has been initialized.
|
||||
bool isValid() const { return fIsValid; }
|
||||
|
||||
GrBackendApi backend() const { return fBackend; }
|
||||
|
||||
private:
|
||||
friend class GrBackendSurfaceMutableStateImpl;
|
||||
friend class GrVkGpu;
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
void setVulkanState(VkImageLayout layout, uint32_t queueFamilyIndex) {
|
||||
SkASSERT(!this->isValid() || fBackend == GrBackendApi::kVulkan);
|
||||
fVkState.setImageLayout(layout);
|
||||
fVkState.setQueueFamilyIndex(queueFamilyIndex);
|
||||
fBackend = GrBackendApi::kVulkan;
|
||||
fIsValid = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
union {
|
||||
char fDummy;
|
||||
#ifdef SK_VULKAN
|
||||
@ -60,7 +84,8 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
GrBackend fBackend;
|
||||
GrBackend fBackend = GrBackendApi::kMock;
|
||||
bool fIsValid = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -687,18 +687,23 @@ public:
|
||||
* called (e.g updateBackendTexture and flush). If finishedProc is not null then it will be
|
||||
* called with finishedContext after the state transition is known to have occurred on the GPU.
|
||||
*
|
||||
* See GrBackendSurfaceMutableState to see what state can be set via this call.
|
||||
*
|
||||
* If the backend API is Vulkan, the caller can set the GrBackendSurfaceMutableState's
|
||||
* VkImageLayout to VK_IMAGE_LAYOUT_UNDEFINED or queueFamilyIndex to VK_QUEUE_FAMILY_IGNORED to
|
||||
* tell Skia to not change those respective states.
|
||||
*
|
||||
* See GrBackendSurfaceMutableState to see what state can be set via this call.
|
||||
* If previousState is not null and this returns true, then Skia will have filled in
|
||||
* previousState to have the values of the state before this call.
|
||||
*/
|
||||
bool setBackendTextureState(const GrBackendTexture&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState = nullptr,
|
||||
GrGpuFinishedProc finishedProc = nullptr,
|
||||
GrGpuFinishedContext finishedContext = nullptr);
|
||||
bool setBackendRenderTargetState(const GrBackendRenderTarget&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState = nullptr,
|
||||
GrGpuFinishedProc finishedProc = nullptr,
|
||||
GrGpuFinishedContext finishedContext = nullptr);
|
||||
|
||||
|
38
src/gpu/GrBackendSurfaceMutableState.cpp
Normal file
38
src/gpu/GrBackendSurfaceMutableState.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/gpu/GrBackendSurfaceMutableState.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
GrBackendSurfaceMutableState::GrBackendSurfaceMutableState(const GrBackendSurfaceMutableState& that)
|
||||
: fBackend(that.fBackend), fIsValid(that.fIsValid) {
|
||||
if (!fIsValid) {
|
||||
return;
|
||||
}
|
||||
switch (fBackend) {
|
||||
case GrBackend::kVulkan:
|
||||
#ifdef SK_VULKAN
|
||||
SkASSERT(that.fBackend == GrBackend::kVulkan);
|
||||
fVkState = that.fVkState;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
(void)that;
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
GrBackendSurfaceMutableState& GrBackendSurfaceMutableState::operator=(
|
||||
const GrBackendSurfaceMutableState& that) {
|
||||
if (this != &that) {
|
||||
this->~GrBackendSurfaceMutableState();
|
||||
new (this) GrBackendSurfaceMutableState(that);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -754,6 +754,7 @@ GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height
|
||||
|
||||
bool GrContext::setBackendTextureState(const GrBackendTexture& backendTexture,
|
||||
const GrBackendSurfaceMutableState& state,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
GrGpuFinishedProc finishedProc,
|
||||
GrGpuFinishedContext finishedContext) {
|
||||
sk_sp<GrRefCntedCallback> callback;
|
||||
@ -769,7 +770,7 @@ bool GrContext::setBackendTextureState(const GrBackendTexture& backendTexture,
|
||||
return false;
|
||||
}
|
||||
|
||||
return fGpu->setBackendTextureState(backendTexture, state, std::move(callback));
|
||||
return fGpu->setBackendTextureState(backendTexture, state, previousState, std::move(callback));
|
||||
}
|
||||
|
||||
bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
|
||||
@ -824,6 +825,7 @@ bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTe
|
||||
|
||||
bool GrContext::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
|
||||
const GrBackendSurfaceMutableState& state,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
GrGpuFinishedProc finishedProc,
|
||||
GrGpuFinishedContext finishedContext) {
|
||||
sk_sp<GrRefCntedCallback> callback;
|
||||
@ -839,7 +841,8 @@ bool GrContext::setBackendRenderTargetState(const GrBackendRenderTarget& backend
|
||||
return false;
|
||||
}
|
||||
|
||||
return fGpu->setBackendRenderTargetState(backendRenderTarget, state, std::move(callback));
|
||||
return fGpu->setBackendRenderTargetState(backendRenderTarget, state, previousState,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void GrContext::deleteBackendTexture(GrBackendTexture backendTex) {
|
||||
|
@ -635,12 +635,14 @@ public:
|
||||
|
||||
virtual bool setBackendTextureState(const GrBackendTexture&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool setBackendRenderTargetState(const GrBackendRenderTarget&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1816,7 +1816,8 @@ void set_layout_and_queue_from_mutable_state(GrVkGpu* gpu, GrVkImage* image,
|
||||
bool GrVkGpu::setBackendSurfaceState(GrVkImageInfo info,
|
||||
sk_sp<GrBackendSurfaceMutableStateImpl> currentState,
|
||||
SkISize dimensions,
|
||||
const GrVkSharedImageInfo& newInfo) {
|
||||
const GrVkSharedImageInfo& newInfo,
|
||||
GrBackendSurfaceMutableState* previousState) {
|
||||
sk_sp<GrVkTexture> texture = GrVkTexture::MakeWrappedTexture(
|
||||
this, dimensions, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType, info,
|
||||
std::move(currentState));
|
||||
@ -1824,32 +1825,39 @@ bool GrVkGpu::setBackendSurfaceState(GrVkImageInfo info,
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
if (previousState) {
|
||||
previousState->setVulkanState(texture->currentLayout(),
|
||||
texture->currentQueueFamilyIndex());
|
||||
}
|
||||
set_layout_and_queue_from_mutable_state(this, texture.get(), newInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrVkGpu::setBackendTextureState(const GrBackendTexture& backendTeture,
|
||||
const GrBackendSurfaceMutableState& newState,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) {
|
||||
GrVkImageInfo info;
|
||||
SkAssertResult(backendTeture.getVkImageInfo(&info));
|
||||
sk_sp<GrBackendSurfaceMutableStateImpl> currentState = backendTeture.getMutableState();
|
||||
SkASSERT(currentState);
|
||||
SkASSERT(newState.fBackend == GrBackend::kVulkan);
|
||||
SkASSERT(newState.isValid() && newState.fBackend == GrBackend::kVulkan);
|
||||
return this->setBackendSurfaceState(info, std::move(currentState), backendTeture.dimensions(),
|
||||
newState.fVkState);
|
||||
newState.fVkState, previousState);
|
||||
}
|
||||
|
||||
bool GrVkGpu::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
|
||||
const GrBackendSurfaceMutableState& newState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) {
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) {
|
||||
GrVkImageInfo info;
|
||||
SkAssertResult(backendRenderTarget.getVkImageInfo(&info));
|
||||
sk_sp<GrBackendSurfaceMutableStateImpl> currentState = backendRenderTarget.getMutableState();
|
||||
SkASSERT(currentState);
|
||||
SkASSERT(newState.fBackend == GrBackend::kVulkan);
|
||||
return this->setBackendSurfaceState(info, std::move(currentState),
|
||||
backendRenderTarget.dimensions(), newState.fVkState);
|
||||
backendRenderTarget.dimensions(), newState.fVkState,
|
||||
previousState);
|
||||
}
|
||||
|
||||
void GrVkGpu::querySampleLocations(GrRenderTarget* renderTarget,
|
||||
|
@ -79,10 +79,12 @@ public:
|
||||
|
||||
bool setBackendTextureState(const GrBackendTexture&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) override;
|
||||
|
||||
bool setBackendRenderTargetState(const GrBackendRenderTarget&,
|
||||
const GrBackendSurfaceMutableState&,
|
||||
GrBackendSurfaceMutableState* previousState,
|
||||
sk_sp<GrRefCntedCallback> finishedCallback) override;
|
||||
|
||||
void deleteBackendTexture(const GrBackendTexture&) override;
|
||||
@ -215,7 +217,8 @@ private:
|
||||
bool setBackendSurfaceState(GrVkImageInfo info,
|
||||
sk_sp<GrBackendSurfaceMutableStateImpl> currentState,
|
||||
SkISize dimensions,
|
||||
const GrVkSharedImageInfo& newInfo);
|
||||
const GrVkSharedImageInfo& newInfo,
|
||||
GrBackendSurfaceMutableState* previousState);
|
||||
|
||||
sk_sp<GrTexture> onCreateTexture(SkISize,
|
||||
const GrBackendFormat&,
|
||||
|
@ -107,41 +107,65 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendSurfaceMutableStateTest, reporter, ctxIn
|
||||
// real transitions to the image so we need to be careful about doing actual valid transitions.
|
||||
GrVkGpu* gpu = static_cast<GrVkGpu*>(dContext->priv().getGpu());
|
||||
|
||||
dContext->setBackendTextureState(backendTex, newState);
|
||||
GrBackendSurfaceMutableState previousState;
|
||||
|
||||
dContext->setBackendTextureState(backendTex, newState, &previousState);
|
||||
|
||||
REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
|
||||
REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout);
|
||||
REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily);
|
||||
|
||||
REPORTER_ASSERT(reporter, previousState.isValid());
|
||||
REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan);
|
||||
REPORTER_ASSERT(reporter, previousState.getVkImageLayout() == initLayout);
|
||||
REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == initQueue);
|
||||
|
||||
// Make sure passing in VK_IMAGE_LAYOUT_UNDEFINED does not change the layout
|
||||
GrBackendSurfaceMutableState noopState(VK_IMAGE_LAYOUT_UNDEFINED, VK_QUEUE_FAMILY_IGNORED);
|
||||
dContext->setBackendTextureState(backendTex, noopState);
|
||||
dContext->setBackendTextureState(backendTex, noopState, &previousState);
|
||||
REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
|
||||
REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout);
|
||||
REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily);
|
||||
|
||||
REPORTER_ASSERT(reporter, previousState.isValid());
|
||||
REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan);
|
||||
REPORTER_ASSERT(reporter,
|
||||
previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == gpu->queueIndex());
|
||||
|
||||
// To test queue transitions, we don't have any other valid queue available so instead we try
|
||||
// to transition to external queue.
|
||||
if (gpu->vkCaps().supportsExternalMemory()) {
|
||||
GrBackendSurfaceMutableState externalState(VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_QUEUE_FAMILY_EXTERNAL);
|
||||
|
||||
dContext->setBackendTextureState(backendTex, externalState);
|
||||
dContext->setBackendTextureState(backendTex, externalState, &previousState);
|
||||
|
||||
REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
|
||||
REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout);
|
||||
REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_EXTERNAL == info.fCurrentQueueFamily);
|
||||
|
||||
REPORTER_ASSERT(reporter, previousState.isValid());
|
||||
REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan);
|
||||
REPORTER_ASSERT(reporter,
|
||||
previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == gpu->queueIndex());
|
||||
|
||||
dContext->submit();
|
||||
|
||||
// Go back to the initial queue. Also we should stay in VK_IMAGE_LAYOUT_GENERAL since we
|
||||
// are passing in VK_IMAGE_LAYOUT_UNDEFINED
|
||||
GrBackendSurfaceMutableState externalState2(VK_IMAGE_LAYOUT_UNDEFINED, initQueue);
|
||||
dContext->setBackendTextureState(backendTex, externalState2);
|
||||
dContext->setBackendTextureState(backendTex, externalState2, &previousState);
|
||||
|
||||
REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info));
|
||||
REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout);
|
||||
REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily);
|
||||
|
||||
REPORTER_ASSERT(reporter, previousState.isValid());
|
||||
REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan);
|
||||
REPORTER_ASSERT(reporter, previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_GENERAL);
|
||||
REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == VK_QUEUE_FAMILY_EXTERNAL);
|
||||
}
|
||||
|
||||
// We must submit this work before we try to delete the backend texture.
|
||||
|
Loading…
Reference in New Issue
Block a user