Commit 9049d321 by Geoff Lang Committed by Commit Bot

Vulkan: Pass the current context to egl Sync operations.

The EGL_KHR_fence_sync spec says that if a flush is needed before waiting on the sync, it's done on the current context for the current thread. This helps simplify the multithreading design, we don't need to worry about flusing on a context that may no longer exist or is executing on a different thread. It does allow infinite waits because the context with the fence is never flushed but the spec allows this. BUG=angleproject:2464 Change-Id: I8bf2f93c408fee2dae95caa5bb9c76ba67687931 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1542256Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 2e5afde1
......@@ -895,7 +895,10 @@ Error Display::createContext(const Config *configuration,
return NoError();
}
Error Display::createSync(EGLenum type, const AttributeMap &attribs, Sync **outSync)
Error Display::createSync(const gl::Context *currentContext,
EGLenum type,
const AttributeMap &attribs,
Sync **outSync)
{
ASSERT(isInitialized());
......@@ -907,7 +910,7 @@ Error Display::createSync(EGLenum type, const AttributeMap &attribs, Sync **outS
angle::UniqueObjectPointer<egl::Sync, Display> syncPtr(new Sync(mImplementation, type, attribs),
this);
ANGLE_TRY(syncPtr->initialize(this));
ANGLE_TRY(syncPtr->initialize(this, currentContext));
Sync *sync = syncPtr.release();
......@@ -1426,14 +1429,4 @@ EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
}
}
Error Display::clientWaitSync(Sync *sync, EGLint flags, EGLTime timeout, EGLint *outResult)
{
return sync->clientWait(this, flags, timeout, outResult);
}
Error Display::waitSync(Sync *sync, EGLint flags)
{
return sync->serverWait(this, flags);
}
} // namespace egl
......@@ -109,7 +109,10 @@ class Display final : public LabeledObject, angle::NonCopyable
const AttributeMap &attribs,
gl::Context **outContext);
Error createSync(EGLenum type, const AttributeMap &attribs, Sync **outSync);
Error createSync(const gl::Context *currentContext,
EGLenum type,
const AttributeMap &attribs,
Sync **outSync);
Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context);
......@@ -170,9 +173,6 @@ class Display final : public LabeledObject, angle::NonCopyable
EGLint binarysize);
EGLint programCacheResize(EGLint limit, EGLenum mode);
Error clientWaitSync(Sync *sync, EGLint flags, EGLTime timeout, EGLint *outResult);
Error waitSync(Sync *sync, EGLint flags);
const AttributeMap &getAttributeMap() const { return mAttributeMap; }
EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; }
......
......@@ -30,19 +30,23 @@ void Sync::onDestroy(const Display *display)
Sync::~Sync() {}
Error Sync::initialize(const Display *display)
Error Sync::initialize(const Display *display, const gl::Context *context)
{
return mFence->initialize(display, mType);
return mFence->initialize(display, context, mType);
}
Error Sync::clientWait(const Display *display, EGLint flags, EGLTime timeout, EGLint *outResult)
Error Sync::clientWait(const Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult)
{
return mFence->clientWait(display, flags, timeout, outResult);
return mFence->clientWait(display, context, flags, timeout, outResult);
}
Error Sync::serverWait(const Display *display, EGLint flags)
Error Sync::serverWait(const Display *display, const gl::Context *context, EGLint flags)
{
return mFence->serverWait(display, flags);
return mFence->serverWait(display, context, flags);
}
Error Sync::getStatus(const Display *display, EGLint *outStatus) const
......
......@@ -22,6 +22,11 @@ class EGLImplFactory;
class EGLSyncImpl;
} // namespace rx
namespace gl
{
class Context;
} // namespace gl
namespace egl
{
class Sync final : public angle::RefCountObject<Display, angle::Result>
......@@ -32,9 +37,13 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>
void onDestroy(const Display *display) override;
Error initialize(const Display *display);
Error clientWait(const Display *display, EGLint flags, EGLTime timeout, EGLint *outResult);
Error serverWait(const Display *display, EGLint flags);
Error initialize(const Display *display, const gl::Context *context);
Error clientWait(const Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult);
Error serverWait(const Display *display, const gl::Context *context, EGLint flags);
Error getStatus(const Display *display, EGLint *outStatus) const;
EGLenum getType() const { return mType; }
......
......@@ -20,6 +20,11 @@ namespace egl
class Display;
} // namespace egl
namespace gl
{
class Context;
} // namespace gl
namespace rx
{
class EGLSyncImpl : angle::NonCopyable
......@@ -30,12 +35,17 @@ class EGLSyncImpl : angle::NonCopyable
virtual void onDestroy(const egl::Display *display) {}
virtual egl::Error initialize(const egl::Display *display, EGLenum type) = 0;
virtual egl::Error initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type) = 0;
virtual egl::Error clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult) = 0;
virtual egl::Error serverWait(const egl::Display *display, EGLint flags) = 0;
virtual egl::Error serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags) = 0;
virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0;
};
} // namespace rx
......
......@@ -31,7 +31,9 @@ void SyncEGL::onDestroy(const egl::Display *display)
mSync = EGL_NO_SYNC_KHR;
}
egl::Error SyncEGL::initialize(const egl::Display *display, EGLenum type)
egl::Error SyncEGL::initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type)
{
ASSERT(type == EGL_SYNC_FENCE_KHR);
mSync = mEGL->createSyncKHR(type, nullptr);
......@@ -43,6 +45,7 @@ egl::Error SyncEGL::initialize(const egl::Display *display, EGLenum type)
}
egl::Error SyncEGL::clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult)
......@@ -59,7 +62,9 @@ egl::Error SyncEGL::clientWait(const egl::Display *display,
return egl::NoError();
}
egl::Error SyncEGL::serverWait(const egl::Display *display, EGLint flags)
egl::Error SyncEGL::serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags)
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
EGLint result = mEGL->waitSyncKHR(mSync, flags);
......
......@@ -29,12 +29,17 @@ class SyncEGL final : public EGLSyncImpl
void onDestroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display, EGLenum type) override;
egl::Error initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type) override;
egl::Error clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult) override;
egl::Error serverWait(const egl::Display *display, EGLint flags) override;
egl::Error serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
private:
......
......@@ -31,11 +31,11 @@ void FenceSyncVk::onDestroy(RendererVk *renderer)
mFence.reset(renderer->getDevice());
}
angle::Result FenceSyncVk::initialize(vk::Context *context)
angle::Result FenceSyncVk::initialize(ContextVk *contextVk)
{
ASSERT(!mEvent.valid());
RendererVk *renderer = context->getRenderer();
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
VkEventCreateInfo eventCreateInfo = {};
......@@ -43,9 +43,9 @@ angle::Result FenceSyncVk::initialize(vk::Context *context)
eventCreateInfo.flags = 0;
vk::Scoped<vk::Event> event(device);
ANGLE_VK_TRY(context, event.get().init(device, eventCreateInfo));
ANGLE_VK_TRY(contextVk, event.get().init(device, eventCreateInfo));
ANGLE_TRY(renderer->getSubmitFence(context, &mFence));
ANGLE_TRY(renderer->getSubmitFence(contextVk, &mFence));
mEvent = event.release();
......@@ -54,6 +54,7 @@ angle::Result FenceSyncVk::initialize(vk::Context *context)
}
angle::Result FenceSyncVk::clientWait(vk::Context *context,
ContextVk *contextVk,
bool flushCommands,
uint64_t timeout,
VkResult *outResult)
......@@ -76,9 +77,9 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context,
return angle::Result::Continue;
}
if (flushCommands)
if (flushCommands && contextVk)
{
ANGLE_TRY(renderer->flush(context));
ANGLE_TRY(contextVk->getRenderer()->flush(contextVk));
}
// Wait on the fence that's expected to be signaled on the first vkQueueSubmit after
......@@ -95,7 +96,7 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context,
return angle::Result::Continue;
}
angle::Result FenceSyncVk::serverWait(vk::Context *context)
angle::Result FenceSyncVk::serverWait(vk::Context *context, ContextVk *contextVk)
{
context->getRenderer()->getCommandGraph()->waitFenceSync(mEvent);
return angle::Result::Continue;
......@@ -141,7 +142,8 @@ angle::Result SyncVk::clientWait(const gl::Context *context,
bool flush = (flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0;
VkResult result;
ANGLE_TRY(mFenceSync.clientWait(contextVk, flush, static_cast<uint64_t>(timeout), &result));
ANGLE_TRY(mFenceSync.clientWait(contextVk, contextVk, flush, static_cast<uint64_t>(timeout),
&result));
switch (result)
{
......@@ -169,7 +171,8 @@ angle::Result SyncVk::serverWait(const gl::Context *context, GLbitfield flags, G
ASSERT(flags == 0);
ASSERT(timeout == GL_TIMEOUT_IGNORED);
return mFenceSync.serverWait(vk::GetImpl(context));
ContextVk *contextVk = vk::GetImpl(context);
return mFenceSync.serverWait(contextVk, contextVk);
}
angle::Result SyncVk::getStatus(const gl::Context *context, GLint *outResult)
......@@ -193,11 +196,14 @@ void EGLSyncVk::onDestroy(const egl::Display *display)
mFenceSync.onDestroy(vk::GetImpl(display)->getRenderer());
}
egl::Error EGLSyncVk::initialize(const egl::Display *display, EGLenum type)
egl::Error EGLSyncVk::initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type)
{
ASSERT(type == EGL_SYNC_FENCE_KHR);
ASSERT(context != nullptr);
if (mFenceSync.initialize(vk::GetImpl(display)) == angle::Result::Stop)
if (mFenceSync.initialize(vk::GetImpl(context)) == angle::Result::Stop)
{
return egl::Error(EGL_BAD_ALLOC, "eglCreateSyncKHR failed to create sync object");
}
......@@ -206,6 +212,7 @@ egl::Error EGLSyncVk::initialize(const egl::Display *display, EGLenum type)
}
egl::Error EGLSyncVk::clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult)
......@@ -215,8 +222,9 @@ egl::Error EGLSyncVk::clientWait(const egl::Display *display,
bool flush = (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) != 0;
VkResult result;
if (mFenceSync.clientWait(vk::GetImpl(display), flush, static_cast<uint64_t>(timeout),
&result) == angle::Result::Stop)
ContextVk *contextVk = context ? vk::GetImpl(context) : nullptr;
if (mFenceSync.clientWait(vk::GetImpl(display), contextVk, flush,
static_cast<uint64_t>(timeout), &result) == angle::Result::Stop)
{
return egl::Error(EGL_BAD_ALLOC);
}
......@@ -241,10 +249,13 @@ egl::Error EGLSyncVk::clientWait(const egl::Display *display,
}
}
egl::Error EGLSyncVk::serverWait(const egl::Display *display, EGLint flags)
egl::Error EGLSyncVk::serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags)
{
ASSERT(flags == 0);
if (mFenceSync.serverWait(vk::GetImpl(display)) == angle::Result::Stop)
ContextVk *contextVk = context ? vk::GetImpl(context) : nullptr;
if (mFenceSync.serverWait(vk::GetImpl(display), contextVk) == angle::Result::Stop)
{
return egl::Error(EGL_BAD_ALLOC);
}
......
......@@ -32,12 +32,13 @@ class FenceSyncVk
void onDestroy(RendererVk *renderer);
angle::Result initialize(vk::Context *context);
angle::Result initialize(ContextVk *contextVk);
angle::Result clientWait(vk::Context *context,
ContextVk *contextVk,
bool flushCommands,
uint64_t timeout,
VkResult *outResult);
angle::Result serverWait(vk::Context *context);
angle::Result serverWait(vk::Context *context, ContextVk *contextVk);
angle::Result getStatus(vk::Context *context, bool *signaled);
private:
......@@ -79,12 +80,17 @@ class EGLSyncVk final : public EGLSyncImpl
void onDestroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display, EGLenum type) override;
egl::Error initialize(const egl::Display *display,
const gl::Context *context,
EGLenum type) override;
egl::Error clientWait(const egl::Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult) override;
egl::Error serverWait(const egl::Display *display, EGLint flags) override;
egl::Error serverWait(const egl::Display *display,
const gl::Context *context,
EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
private:
......
......@@ -13,6 +13,7 @@
#include "common/version.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Texture.h"
#include "libANGLE/Thread.h"
......@@ -857,7 +858,7 @@ EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(type, attributes, &syncObject),
ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
thread->setSuccess();
......@@ -898,9 +899,11 @@ EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags
ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(thread, display->clientWaitSync(syncObject, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(
thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return syncStatus;
......@@ -1056,8 +1059,9 @@ EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
"eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitSync(syncObject, flags), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
"eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
......
......@@ -12,6 +12,7 @@
#include "libANGLE/Context.h"
#include "libANGLE/Device.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Stream.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Thread.h"
......@@ -897,7 +898,7 @@ ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(type, attributes, &syncObject),
ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
thread->setSuccess();
......@@ -941,9 +942,11 @@ ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(thread, display->clientWaitSync(syncObject, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(
thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return syncStatus;
......@@ -990,8 +993,9 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSync sync
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
"eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitSync(syncObject, flags), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
"eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment