aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/vk')
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp96
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h4
-rw-r--r--src/gpu/vk/GrVkGpu.cpp24
-rw-r--r--src/gpu/vk/GrVkGpu.h15
-rw-r--r--src/gpu/vk/GrVkSemaphore.cpp14
-rw-r--r--src/gpu/vk/GrVkSemaphore.h42
6 files changed, 139 insertions, 56 deletions
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index 8a17a4f033..27642dfe63 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -445,12 +445,36 @@ void GrVkPrimaryCommandBuffer::executeCommands(const GrVkGpu* gpu,
this->invalidateState();
}
+static void submit_to_queue(const GrVkInterface* interface,
+ VkQueue queue,
+ VkFence fence,
+ uint32_t waitCount,
+ const VkSemaphore* waitSemaphores,
+ const VkPipelineStageFlags* waitStages,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* commandBuffers,
+ uint32_t signalCount,
+ const VkSemaphore* signalSemaphores) {
+ VkSubmitInfo submitInfo;
+ memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = waitCount;
+ submitInfo.pWaitSemaphores = waitSemaphores;
+ submitInfo.pWaitDstStageMask = waitStages;
+ submitInfo.commandBufferCount = commandBufferCount;
+ submitInfo.pCommandBuffers = commandBuffers;
+ submitInfo.signalSemaphoreCount = signalCount;
+ submitInfo.pSignalSemaphores = signalSemaphores;
+ GR_VK_CALL_ERRCHECK(interface, QueueSubmit(queue, 1, &submitInfo, fence));
+}
+
void GrVkPrimaryCommandBuffer::submitToQueue(
const GrVkGpu* gpu,
VkQueue queue,
GrVkGpu::SyncQueue sync,
- SkTArray<const GrVkSemaphore::Resource*>& signalSemaphores,
- SkTArray<const GrVkSemaphore::Resource*>& waitSemaphores) {
+ SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
+ SkTArray<GrVkSemaphore::Resource*>& waitSemaphores) {
SkASSERT(!fIsActive);
VkResult err;
@@ -466,33 +490,51 @@ void GrVkPrimaryCommandBuffer::submitToQueue(
}
int signalCount = signalSemaphores.count();
- SkTArray<VkSemaphore> vkSignalSem(signalCount);
- for (int i = 0; i < signalCount; ++i) {
- this->addResource(signalSemaphores[i]);
- vkSignalSem.push_back(signalSemaphores[i]->semaphore());
- }
-
int waitCount = waitSemaphores.count();
- SkTArray<VkSemaphore> vkWaitSems(waitCount);
- SkTArray<VkPipelineStageFlags> vkWaitStages(waitCount);
- for (int i = 0; i < waitCount; ++i) {
- this->addResource(waitSemaphores[i]);
- vkWaitSems.push_back(waitSemaphores[i]->semaphore());
- vkWaitStages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
- }
- VkSubmitInfo submitInfo;
- memset(&submitInfo, 0, sizeof(VkSubmitInfo));
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = waitCount;
- submitInfo.pWaitSemaphores = vkWaitSems.begin();
- submitInfo.pWaitDstStageMask = vkWaitStages.begin();
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &fCmdBuffer;
- submitInfo.signalSemaphoreCount = vkSignalSem.count();
- submitInfo.pSignalSemaphores = vkSignalSem.begin();
- GR_VK_CALL_ERRCHECK(gpu->vkInterface(), QueueSubmit(queue, 1, &submitInfo, fSubmitFence));
+ if (0 == signalCount && 0 == waitCount) {
+ // This command buffer has no dependent semaphores so we can simply just submit it to the
+ // queue with no worries.
+ submit_to_queue(gpu->vkInterface(), queue, fSubmitFence, 0, nullptr, nullptr,
+ 1, &fCmdBuffer, 0, nullptr);
+ } else {
+ GrVkSemaphore::Resource::AcquireMutex();
+
+ SkTArray<VkSemaphore> vkSignalSems(signalCount);
+ for (int i = 0; i < signalCount; ++i) {
+ if (signalSemaphores[i]->shouldSignal()) {
+ this->addResource(signalSemaphores[i]);
+ vkSignalSems.push_back(signalSemaphores[i]->semaphore());
+ }
+ }
+
+ SkTArray<VkSemaphore> vkWaitSems(waitCount);
+ SkTArray<VkPipelineStageFlags> vkWaitStages(waitCount);
+ for (int i = 0; i < waitCount; ++i) {
+ if (waitSemaphores[i]->shouldWait()) {
+ this->addResource(waitSemaphores[i]);
+ vkWaitSems.push_back(waitSemaphores[i]->semaphore());
+ vkWaitStages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+ }
+ }
+ submit_to_queue(gpu->vkInterface(), queue, fSubmitFence,
+ vkWaitSems.count(), vkWaitSems.begin(), vkWaitStages.begin(),
+ 1, &fCmdBuffer,
+ vkSignalSems.count(), vkSignalSems.begin());
+ // Since shouldSignal/Wait do not require a mutex to be held, we must make sure that we mark
+ // the semaphores after we've submitted. Thus in the worst case another submit grabs the
+ // mutex and then realizes it doesn't need to submit the semaphore. We will never end up
+ // where a semaphore doesn't think it needs to be submitted (cause of querying
+ // shouldSignal/Wait), but it should need to.
+ for (int i = 0; i < signalCount; ++i) {
+ signalSemaphores[i]->markAsSignaled();
+ }
+ for (int i = 0; i < waitCount; ++i) {
+ waitSemaphores[i]->markAsWaited();
+ }
+
+ GrVkSemaphore::Resource::ReleaseMutex();
+ }
if (GrVkGpu::kForce_SyncQueue == sync) {
err = GR_VK_CALL(gpu->vkInterface(),
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index 7d16242e6b..362d457773 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -269,8 +269,8 @@ public:
const VkImageResolve* regions);
void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync,
- SkTArray<const GrVkSemaphore::Resource*>& signalSemaphores,
- SkTArray<const GrVkSemaphore::Resource*>& waitSemaphores);
+ SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
+ SkTArray<GrVkSemaphore::Resource*>& waitSemaphores);
bool finished(const GrVkGpu* gpu) const;
#ifdef SK_TRACE_VK_RESOURCES
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index e1be99e872..f7e3d47dd9 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -2162,16 +2162,17 @@ sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore(bool isOwned) {
return GrVkSemaphore::Make(this, isOwned);
}
-sk_sp<GrSemaphore> GrVkGpu::onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) {
- return GrVkSemaphore::MakeWrapped(this, semaphore.vkSemaphore(), ownership);
+sk_sp<GrSemaphore> GrVkGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrResourceProvider::SemaphoreWrapType wrapType,
+ GrWrapOwnership ownership) {
+ return GrVkSemaphore::MakeWrapped(this, semaphore.vkSemaphore(), wrapType, ownership);
}
-void GrVkGpu::onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
+void GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
- if (vkSem) {
- const GrVkSemaphore::Resource* resource = vkSem->getResource();
+ GrVkSemaphore::Resource* resource = vkSem->getResource();
+ if (resource->shouldSignal()) {
resource->ref();
fSemaphoresToSignal.push_back(resource);
}
@@ -2181,13 +2182,14 @@ void GrVkGpu::onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
}
}
-void GrVkGpu::onWaitSemaphore(sk_sp<GrSemaphore> semaphore) {
+void GrVkGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
- SkASSERT(vkSem);
- const GrVkSemaphore::Resource* resource = vkSem->getResource();
- resource->ref();
- fSemaphoresToWaitOn.push_back(resource);
+ GrVkSemaphore::Resource* resource = vkSem->getResource();
+ if (resource->shouldWait()) {
+ resource->ref();
+ fSemaphoresToWaitOn.push_back(resource);
+ }
}
sk_sp<GrSemaphore> GrVkGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index e3055945bc..8cc98d9da1 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -135,6 +135,12 @@ public:
void deleteFence(GrFence) const override;
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
+ sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrResourceProvider::SemaphoreWrapType wrapType,
+ GrWrapOwnership ownership) override;
+ void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
+ void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
+
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
void generateMipmap(GrVkTexture* tex, GrSurfaceOrigin texOrigin);
@@ -204,11 +210,6 @@ private:
void onFinishFlush(bool insertedSemaphores) override;
- void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
- void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) override;
- sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override;
-
// Ends and submits the current command buffer to the queue and then creates a new command
// buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all
// work in the queue to finish before returning. If this GrVkGpu object has any semaphores in
@@ -265,8 +266,8 @@ private:
GrVkPrimaryCommandBuffer* fCurrentCmdBuffer;
- SkSTArray<1, const GrVkSemaphore::Resource*> fSemaphoresToWaitOn;
- SkSTArray<1, const GrVkSemaphore::Resource*> fSemaphoresToSignal;
+ SkSTArray<1, GrVkSemaphore::Resource*> fSemaphoresToWaitOn;
+ SkSTArray<1, GrVkSemaphore::Resource*> fSemaphoresToSignal;
VkPhysicalDeviceMemoryProperties fPhysDevMemProps;
diff --git a/src/gpu/vk/GrVkSemaphore.cpp b/src/gpu/vk/GrVkSemaphore.cpp
index 38946f4566..4a23c43eea 100644
--- a/src/gpu/vk/GrVkSemaphore.cpp
+++ b/src/gpu/vk/GrVkSemaphore.cpp
@@ -16,6 +16,8 @@
#undef CreateSemaphore
#endif
+SkMutex GrVkSemaphore::Resource::gMutex;
+
sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu, bool isOwned) {
VkSemaphoreCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkSemaphoreCreateInfo));
@@ -26,22 +28,26 @@ sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu, bool isOwned) {
GR_VK_CALL_ERRCHECK(gpu->vkInterface(),
CreateSemaphore(gpu->device(), &createInfo, nullptr, &semaphore));
- return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore, isOwned));
+ return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore, false, false, isOwned));
}
sk_sp<GrVkSemaphore> GrVkSemaphore::MakeWrapped(const GrVkGpu* gpu,
VkSemaphore semaphore,
+ WrapType wrapType,
GrWrapOwnership ownership) {
if (VK_NULL_HANDLE == semaphore) {
return nullptr;
}
- return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore,
+ bool prohibitSignal = WrapType::kWillWait == wrapType;
+ bool prohibitWait = WrapType::kWillSignal == wrapType;
+ return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore, prohibitSignal, prohibitWait,
kBorrow_GrWrapOwnership != ownership));
}
-GrVkSemaphore::GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool isOwned)
+GrVkSemaphore::GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal,
+ bool prohibitWait, bool isOwned)
: INHERITED(gpu) {
- fResource = new Resource(semaphore, isOwned);
+ fResource = new Resource(semaphore, prohibitSignal, prohibitWait, isOwned);
}
GrVkSemaphore::~GrVkSemaphore() {
diff --git a/src/gpu/vk/GrVkSemaphore.h b/src/gpu/vk/GrVkSemaphore.h
index b99eb944f7..36d1e6ee5d 100644
--- a/src/gpu/vk/GrVkSemaphore.h
+++ b/src/gpu/vk/GrVkSemaphore.h
@@ -9,6 +9,8 @@
#define GrVkSemaphore_DEFINED
#include "GrSemaphore.h"
+
+#include "GrResourceProvider.h"
#include "GrVkResource.h"
#include "vk/GrVkTypes.h"
@@ -20,21 +22,47 @@ class GrVkSemaphore : public GrSemaphore {
public:
static sk_sp<GrVkSemaphore> Make(const GrVkGpu* gpu, bool isOwned);
+ using WrapType = GrResourceProvider::SemaphoreWrapType;
+
static sk_sp<GrVkSemaphore> MakeWrapped(const GrVkGpu* gpu,
VkSemaphore semaphore,
+ WrapType wrapType,
GrWrapOwnership);
~GrVkSemaphore() override;
class Resource : public GrVkResource {
public:
- Resource(VkSemaphore semaphore, bool isOwned)
- : INHERITED(), fSemaphore(semaphore), fIsOwned(isOwned) {}
+ Resource(VkSemaphore semaphore, bool prohibitSignal, bool prohibitWait, bool isOwned)
+ : INHERITED()
+ , fSemaphore(semaphore)
+ , fHasBeenSubmittedToQueueForSignal(prohibitSignal)
+ , fHasBeenSubmittedToQueueForWait(prohibitWait)
+ , fIsOwned(isOwned) {}
~Resource() override {}
VkSemaphore semaphore() const { return fSemaphore; }
+ static void AcquireMutex() { gMutex.acquire(); }
+ static void ReleaseMutex() { gMutex.release(); }
+
+ bool shouldSignal() const {
+ return !fHasBeenSubmittedToQueueForSignal;
+ }
+ bool shouldWait() const {
+ return !fHasBeenSubmittedToQueueForWait;
+ }
+
+ void markAsSignaled() {
+ gMutex.assertHeld();
+ fHasBeenSubmittedToQueueForSignal = true;
+ }
+ void markAsWaited() {
+ gMutex.assertHeld();
+ fHasBeenSubmittedToQueueForWait = true;
+ }
+
#ifdef SK_TRACE_VK_RESOURCES
void dumpInfo() const override {
SkDebugf("GrVkSemaphore: %d (%d refs)\n", fSemaphore, this->getRefCnt());
@@ -43,20 +71,24 @@ public:
private:
void freeGPUData(const GrVkGpu* gpu) const override;
+ static SkMutex gMutex;
VkSemaphore fSemaphore;
+ bool fHasBeenSubmittedToQueueForSignal;
+ bool fHasBeenSubmittedToQueueForWait;
bool fIsOwned;
typedef GrVkResource INHERITED;
};
- const Resource* getResource() const { return fResource; }
+ Resource* getResource() { return fResource; }
private:
- GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool isOwned);
+ GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool prohibitSignal, bool prohibitWait,
+ bool isOwned);
void setBackendSemaphore(GrBackendSemaphore*) const override;
- const Resource* fResource;
+ Resource* fResource;
typedef GrSemaphore INHERITED;
};