Commit ab6a59b2 by Michael Spang Committed by Commit Bot

Vulkan: Submit semaphores from glWaitSemaphoreEXT & glSignalSemaphoreEXT

Implement submission of client semaphores passed to glWaitSemaphoreEXT & glSignalSemaphoreEXT. This also relaxes the expectation that we will not flush() if there are no commands. Signaling semaphores in particular requires queue submission irrespective of whether there are any command buffers to submit. If there are neither commands nor semaphores, we can still skip queue submission. WebGL runs in Chrome with ANGLE & Vulkan interop as of this patch, albeit with incorrect synchronization due to texture barriers not being implemented yet. Quite a few flags are needed to try this: GN args: angle_vulkan_conformant_configs_only=true chrome \ --enable-features=UseSkiaRenderer,UiGpuRasterization \ --enable-gpu-rasterization \ --enable-oop-rasterization \ --enable-vulkan \ --use-gl=angle \ --use-angle=vulkan Bug: angleproject:3289 Change-Id: I3d49c230a2fbf0cd2a2b943b05ded0e4604cc313 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1623815 Commit-Queue: Michael Spang <spang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d3e7a41b
......@@ -7256,24 +7256,32 @@ void Context::getSemaphoreParameterui64v(GLuint semaphore, GLenum pname, GLuint6
UNIMPLEMENTED();
}
void Context::waitSemaphore(GLuint semaphore,
void Context::waitSemaphore(GLuint semaphoreHandle,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts)
{
UNIMPLEMENTED();
Semaphore *semaphore = getSemaphore(semaphoreHandle);
ASSERT(semaphore);
ANGLE_CONTEXT_TRY(mImplementation->waitSemaphore(this, semaphore, numBufferBarriers, buffers,
numTextureBarriers, textures, srcLayouts));
}
void Context::signalSemaphore(GLuint semaphore,
void Context::signalSemaphore(GLuint semaphoreHandle,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
UNIMPLEMENTED();
Semaphore *semaphore = getSemaphore(semaphoreHandle);
ASSERT(semaphore);
ANGLE_CONTEXT_TRY(mImplementation->signalSemaphore(this, semaphore, numBufferBarriers, buffers,
numTextureBarriers, textures, dstLayouts));
}
void Context::importSemaphoreFd(GLuint semaphore, HandleType handleType, GLint fd)
......
......@@ -220,6 +220,7 @@ MSG kInvalidFramebufferTarget = "Invalid framebuffer target.";
MSG kInvalidFramebufferTextureLevel = "Mipmap level must be 0 when attaching a texture.";
MSG kInvalidHandleType = "Invalid handle type.";
MSG kInvalidImageAccess = "access is not one of the supported tokens.";
MSG kInvalidImageLayout = "Invalid image layout.";
MSG kInvalidImageFormat = "format is not one of supported image unit formats.";
MSG kInvalidIndentifier = "Invalid identifier.";
MSG kInvalidIndirectOffset = "indirect must be a multiple of the size of uint in basic machine units.";
......
......@@ -21,6 +21,7 @@ namespace gl
class ErrorSet;
class MemoryProgramCache;
class Path;
class Semaphore;
struct Workarounds;
} // namespace gl
......@@ -40,6 +41,22 @@ class ContextImpl : public GLImplFactory
virtual angle::Result flush(const gl::Context *context) = 0;
virtual angle::Result finish(const gl::Context *context) = 0;
// Semaphore operations.
virtual angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) = 0;
virtual angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) = 0;
// Drawing methods.
virtual angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -253,6 +253,30 @@ angle::Result Context11::finish(const gl::Context *context)
return mRenderer->finish(this);
}
angle::Result Context11::waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result Context11::signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result Context11::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
GLint first,
......
......@@ -75,6 +75,22 @@ class Context11 : public ContextD3D, public MultisampleTextureInitializer
angle::Result flush(const gl::Context *context) override;
angle::Result finish(const gl::Context *context) override;
// Semaphore operations.
angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) override;
angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) override;
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -155,6 +155,30 @@ angle::Result Context9::finish(const gl::Context *context)
return mRenderer->finish(context);
}
angle::Result Context9::waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result Context9::signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result Context9::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
GLint first,
......
......@@ -74,6 +74,22 @@ class Context9 : public ContextD3D
angle::Result flush(const gl::Context *context) override;
angle::Result finish(const gl::Context *context) override;
// Semaphore operations.
angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) override;
angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) override;
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -190,6 +190,30 @@ angle::Result ContextGL::finish(const gl::Context *context)
return mRenderer->finish();
}
angle::Result ContextGL::waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
angle::Result ContextGL::signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
ANGLE_GL_UNREACHABLE(this);
return angle::Result::Stop;
}
ANGLE_INLINE angle::Result ContextGL::setDrawArraysState(const gl::Context *context,
GLint first,
GLsizei count,
......
......@@ -85,6 +85,22 @@ class ContextGL : public ContextImpl
angle::Result flush(const gl::Context *context) override;
angle::Result finish(const gl::Context *context) override;
// Semaphore operations.
angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) override;
angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) override;
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -121,6 +121,30 @@ angle::Result ContextNULL::finish(const gl::Context *context)
return angle::Result::Continue;
}
angle::Result ContextNULL::waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts
)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
return angle::Result::Continue;
}
angle::Result ContextNULL::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
GLint first,
......
......@@ -44,6 +44,22 @@ class ContextNULL : public ContextImpl
angle::Result flush(const gl::Context *context) override;
angle::Result finish(const gl::Context *context) override;
// Semaphore operations.
angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) override;
angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) override;
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......
......@@ -14,6 +14,7 @@
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/Program.h"
#include "libANGLE/Semaphore.h"
#include "libANGLE/Surface.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/renderer_utils.h"
......@@ -81,7 +82,7 @@ void InitializeSubmitInfo(VkSubmitInfo *submitInfo,
const SignalSemaphoreVector &signalSemaphores)
{
submitInfo->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo->commandBufferCount = 1;
submitInfo->commandBufferCount = commandBuffer.valid() ? 1 : 0;
submitInfo->pCommandBuffers = commandBuffer.ptr();
submitInfo->waitSemaphoreCount = waitSemaphores.size();
......@@ -308,7 +309,7 @@ angle::Result ContextVk::initialize()
angle::Result ContextVk::flush(const gl::Context *context)
{
return flushImpl();
return flushImpl(nullptr);
}
angle::Result ContextVk::finish(const gl::Context *context)
......@@ -316,6 +317,54 @@ angle::Result ContextVk::finish(const gl::Context *context)
return finishImpl();
}
angle::Result ContextVk::waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts)
{
mWaitSemaphores.push_back(vk::GetImpl(semaphore)->getHandle());
if (numBufferBarriers != 0)
{
// Buffers in external memory are not implemented yet.
UNIMPLEMENTED();
}
if (numTextureBarriers != 0)
{
// Texture barriers are not implemented yet.
UNIMPLEMENTED();
}
return angle::Result::Continue;
}
angle::Result ContextVk::signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts)
{
if (numBufferBarriers != 0)
{
// Buffers in external memory are not implemented yet.
UNIMPLEMENTED();
}
if (numTextureBarriers != 0)
{
// Texture barriers are not implemented yet.
UNIMPLEMENTED();
}
return flushImpl(semaphore);
}
angle::Result ContextVk::setupDraw(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
......@@ -1630,7 +1679,7 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
angle::Result ContextVk::onUnMakeCurrent(const gl::Context *context)
{
ANGLE_TRY(flushImpl());
ANGLE_TRY(flushImpl(nullptr));
mCurrentWindowSurface = nullptr;
return angle::Result::Continue;
}
......@@ -1968,9 +2017,9 @@ const gl::ActiveTextureArray<TextureVk *> &ContextVk::getActiveTextures() const
return mActiveTextures;
}
angle::Result ContextVk::flushImpl()
angle::Result ContextVk::flushImpl(const gl::Semaphore *clientSignalSemaphore)
{
if (mCommandGraph.empty())
if (mCommandGraph.empty() && !clientSignalSemaphore && mWaitSemaphores.empty())
{
return angle::Result::Continue;
}
......@@ -1978,11 +2027,19 @@ angle::Result ContextVk::flushImpl()
TRACE_EVENT0("gpu.angle", "ContextVk::flush");
vk::Scoped<vk::PrimaryCommandBuffer> commandBatch(getDevice());
ANGLE_TRY(flushCommandGraph(&commandBatch.get()));
if (!mCommandGraph.empty())
{
ANGLE_TRY(flushCommandGraph(&commandBatch.get()));
}
SignalSemaphoreVector signalSemaphores;
ANGLE_TRY(generateSurfaceSemaphores(&signalSemaphores));
if (clientSignalSemaphore)
{
signalSemaphores.push_back(vk::GetImpl(clientSignalSemaphore)->getHandle());
}
VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), mWaitSemaphores, &waitMask,
......@@ -1999,7 +2056,7 @@ angle::Result ContextVk::finishImpl()
{
TRACE_EVENT0("gpu.angle", "ContextVk::finish");
ANGLE_TRY(flushImpl());
ANGLE_TRY(flushImpl(nullptr));
ANGLE_TRY(finishToSerial(mLastSubmittedQueueSerial));
freeAllInFlightResources();
......
......@@ -41,6 +41,22 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
angle::Result flush(const gl::Context *context) override;
angle::Result finish(const gl::Context *context) override;
// Semaphore operations.
angle::Result waitSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *srcLayouts) override;
angle::Result signalSemaphore(const gl::Context *context,
const gl::Semaphore *semaphore,
GLuint numBufferBarriers,
const GLuint *buffers,
GLuint numTextureBarriers,
const GLuint *textures,
const GLenum *dstLayouts) override;
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
......@@ -218,7 +234,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void setIndexBufferDirty() { mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); }
angle::Result flushImpl();
angle::Result flushImpl(const gl::Semaphore *semaphore);
angle::Result finishImpl();
const vk::CommandPool &getCommandPool() const;
......
......@@ -155,7 +155,7 @@ angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sib
ContextVk *contextVk = vk::GetImpl(mContext);
// Flush the context to make sure the fence has been submitted.
ANGLE_TRY(contextVk->flushImpl());
ANGLE_TRY(contextVk->flushImpl(nullptr));
vk::Shared<vk::Fence> fence = contextVk->getLastSubmittedFence();
if (fence.isReferenced())
......
......@@ -110,7 +110,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
// has pending work should flush begin too.
if (mQueryHelper.hasPendingWork(contextVk))
{
ANGLE_TRY(contextVk->flushImpl());
ANGLE_TRY(contextVk->flushImpl(nullptr));
ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(contextVk));
ASSERT(!mQueryHelper.hasPendingWork(contextVk));
......
......@@ -893,7 +893,7 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
}
image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::Present, swapCommands);
ANGLE_TRY(contextVk->flushImpl());
ANGLE_TRY(contextVk->flushImpl(nullptr));
// The semaphore chain must at least have the semaphore returned by vkAquireImage in it. It will
// likely have more based on how much work was flushed this frame.
......
......@@ -87,7 +87,7 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context,
if (flushCommands && contextVk)
{
ANGLE_TRY(contextVk->flushImpl());
ANGLE_TRY(contextVk->flushImpl(nullptr));
}
// Wait on the fence that's expected to be signaled on the first vkQueueSubmit after
......
......@@ -502,7 +502,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion.enabled)
{
ANGLE_TRY(contextVk->flushImpl());
ANGLE_TRY(contextVk->flushImpl(nullptr));
}
return angle::Result::Continue;
......
......@@ -27,6 +27,7 @@
PROC(Framebuffer) \
PROC(MemoryObject) \
PROC(Program) \
PROC(Semaphore) \
PROC(Texture) \
PROC(VertexArray)
......
......@@ -1124,6 +1124,27 @@ bool ValidDstBlendFunc(const Context *context, GLenum val)
return false;
}
bool IsValidImageLayout(ImageLayout layout)
{
switch (layout)
{
case ImageLayout::General:
case ImageLayout::ColorAttachment:
case ImageLayout::DepthStencilAttachment:
case ImageLayout::DepthStencilReadOnlyAttachment:
case ImageLayout::ShaderReadOnly:
case ImageLayout::TransferSrc:
case ImageLayout::TransferDst:
case ImageLayout::DepthReadOnlyStencilAttachment:
case ImageLayout::DepthAttachmentStencilReadOnly:
return true;
default:
return false;
}
}
} // anonymous namespace
bool ValidateES2TexImageParameters(Context *context,
......@@ -3341,8 +3362,16 @@ bool ValidateSignalSemaphoreEXT(Context *context,
return false;
}
UNIMPLEMENTED();
return false;
for (GLuint i = 0; i < numTextureBarriers; ++i)
{
if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
{
context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
return false;
}
}
return true;
}
bool ValidateWaitSemaphoreEXT(Context *context,
......@@ -3359,8 +3388,16 @@ bool ValidateWaitSemaphoreEXT(Context *context,
return false;
}
UNIMPLEMENTED();
return false;
for (GLuint i = 0; i < numTextureBarriers; ++i)
{
if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
{
context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
return false;
}
}
return true;
}
bool ValidateImportSemaphoreFdEXT(Context *context,
......
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