Commit 20b1259a by Jamie Madill Committed by Commit Bot

Vulkan: Command graph linearization (Step 2).

ES 2.0 is feature complete. Passes all of the angle_end2end_tests with the new linear command recording method. Also runs the T-Rex benchmark without any obvious glitches. Likely has issues with creating too many RenderPasses. ES3 is mostly untouched. Bug: angleproject:4029 Change-Id: Ic5acf3d768495fbffd07b07bf0a6f2b5787c51f8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2012900Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 806ba566
......@@ -229,8 +229,8 @@ angle::Result BufferVk::copySubData(const gl::Context *context,
}
else
{
contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &sourceBuffer->getBuffer());
contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, &mBuffer);
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &sourceBuffer->getBuffer()));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
......@@ -421,8 +421,8 @@ angle::Result BufferVk::copyToBuffer(ContextVk *contextVk,
}
else
{
contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer);
contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &mBuffer);
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
......
......@@ -95,31 +95,43 @@ class CommandQueue final : angle::NonCopyable
vk::PersistentCommandPool mPrimaryCommandPool;
};
class OutsideRenderPassCommandBuffer final : angle::NonCopyable
struct CommandBufferHelper : angle::NonCopyable
{
public:
OutsideRenderPassCommandBuffer();
~OutsideRenderPassCommandBuffer();
void bufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer);
void bufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer);
void flushToPrimary(vk::PrimaryCommandBuffer *primary);
void bufferRead(vk::ResourceUseList *resourceUseList,
VkAccessFlags readAccessType,
vk::BufferHelper *buffer);
void bufferWrite(vk::ResourceUseList *resourceUseList,
VkAccessFlags writeAccessType,
vk::BufferHelper *buffer);
vk::CommandBuffer &getCommandBuffer() { return mCommandBuffer; }
bool empty() const { return mCommandBuffer.empty(); }
void reset();
protected:
CommandBufferHelper();
~CommandBufferHelper();
void recordBarrier(vk::PrimaryCommandBuffer *primary);
private:
VkFlags mGlobalMemoryBarrierSrcAccess;
VkFlags mGlobalMemoryBarrierDstAccess;
VkPipelineStageFlags mGlobalMemoryBarrierStages;
vk::CommandBuffer mCommandBuffer;
};
class RenderPassCommandBuffer final : angle::NonCopyable
class OutsideRenderPassCommandBuffer final : public CommandBufferHelper
{
public:
OutsideRenderPassCommandBuffer();
~OutsideRenderPassCommandBuffer();
void flushToPrimary(vk::PrimaryCommandBuffer *primary);
bool empty() const { return mCommandBuffer.empty(); }
void reset();
};
class RenderPassCommandBuffer final : public CommandBufferHelper
{
public:
RenderPassCommandBuffer();
......@@ -167,9 +179,11 @@ class RenderPassCommandBuffer final : angle::NonCopyable
mAttachmentOps[attachmentIndex].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
const gl::Rectangle &getRenderArea() const { return mRenderArea; }
angle::Result flushToPrimary(ContextVk *contextVk, vk::PrimaryCommandBuffer *primary);
bool empty() const { return mCommandBuffer.empty(); }
bool empty() const { return !mRenderPassStarted; }
void reset();
uint32_t getAndResetCounter()
......@@ -186,7 +200,7 @@ class RenderPassCommandBuffer final : angle::NonCopyable
vk::Framebuffer mFramebuffer;
gl::Rectangle mRenderArea;
gl::AttachmentArray<VkClearValue> mClearValues;
vk::CommandBuffer mCommandBuffer;
bool mRenderPassStarted;
};
class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassOwner
......@@ -517,7 +531,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
Serial generateTextureSerial() { return mTextureSerialFactory.generate(); }
const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; }
void updateScissor(const gl::State &glState);
angle::Result updateScissor(const gl::State &glState);
bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; }
......@@ -527,13 +541,22 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }
void onBufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer);
void onBufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer);
angle::Result onBufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer);
angle::Result onBufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer);
angle::Result onImageRead(VkImageAspectFlags aspectFlags,
vk::ImageLayout imageLayout,
vk::ImageHelper *image);
angle::Result onImageWrite(VkImageAspectFlags aspectFlags,
vk::ImageLayout imageLayout,
vk::ImageHelper *image);
angle::Result getOutsideRenderPassCommandBuffer(vk::CommandBuffer **commandBufferOut)
{
if (!mRenderPassCommands.empty())
{
ANGLE_TRY(mRenderPassCommands.flushToPrimary(this, &mPrimaryCommands));
ANGLE_TRY(endRenderPass());
}
*commandBufferOut = &mOutsideRenderPassCommands.getCommandBuffer();
return angle::Result::Continue;
......@@ -556,6 +579,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
}
egl::ContextPriority getContextPriority() const override { return mContextPriority; }
angle::Result endRenderPass();
private:
// Dirty bits.
......
......@@ -859,19 +859,27 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
const UtilsVk::BlitResolveParameters &params,
vk::ImageHelper *srcImage)
{
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
}
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
}
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
// Source's layout change should happen before rendering
srcImage->addReadDependency(contextVk, &mFramebuffer);
// Source's layout change should happen before rendering
srcImage->addReadDependency(contextVk, &mFramebuffer);
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcImage));
}
VkImageResolve resolveRegion = {};
resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
......@@ -893,9 +901,20 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{
RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL];
vk::ImageHelper *drawImage = drawRenderTarget->getImageForWrite(contextVk, &mFramebuffer);
drawImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
if (contextVk->commandGraphEnabled())
{
vk::ImageHelper *drawImage =
drawRenderTarget->getImageForWrite(contextVk, &mFramebuffer);
drawImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst,
&drawRenderTarget->getImage()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
resolveRegion.dstSubresource.mipLevel = drawRenderTarget->getLevelIndex();
resolveRegion.dstSubresource.baseArrayLayer = drawRenderTarget->getLayerIndex();
......@@ -1074,7 +1093,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
// The FBOs new attachment may have changed the renderable area
const gl::State &glState = context->getState();
contextVk->updateScissor(glState);
ANGLE_TRY(contextVk->updateScissor(glState));
mActiveColorComponents = gl_vk::GetColorComponentFlags(
mActiveColorComponentMasksForClear[0].any(), mActiveColorComponentMasksForClear[1].any(),
......@@ -1088,6 +1107,10 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
// create a new entry in the command graph.
mFramebuffer.finishCurrentCommands(contextVk);
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
// Notify the ContextVk to update the pipeline desc.
updateRenderPassDesc();
......@@ -1222,7 +1245,7 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
// render pass is needed,
// - the current render area doesn't match the clear area. We need the render area to be
// exactly as specified by the scissor for the loadOp to clear only that area. See
// onScissorChange for more information.
// ContextVk::updateScissor for more information.
if (!mFramebuffer.valid() || !mFramebuffer.renderPassStartedButEmpty() ||
mFramebuffer.getRenderPassRenderArea() != clearArea)
......@@ -1468,28 +1491,6 @@ gl::Rectangle FramebufferVk::getScissoredRenderArea(ContextVk *contextVk) const
return ClipRectToScissor(contextVk->getState(), renderArea, invertViewport);
}
void FramebufferVk::onScissorChange(ContextVk *contextVk)
{
gl::Rectangle scissoredRenderArea = getScissoredRenderArea(contextVk);
// If the scissor has grown beyond the previous scissoredRenderArea, make sure the render pass
// is restarted. Otherwise, we can continue using the same renderpass area.
//
// Without a scissor, the render pass area covers the whole of the framebuffer. With a
// scissored clear, the render pass area could be smaller than the framebuffer size. When the
// scissor changes, if the scissor area is completely encompassed by the render pass area, it's
// possible to continue using the same render pass. However, if the current render pass area
// is too small, we need to start a new one. The latter can happen if a scissored clear starts
// a render pass, the scissor is disabled and a draw call is issued to affect the whole
// framebuffer.
mFramebuffer.updateCurrentAccessNodes();
if (mFramebuffer.hasStartedRenderPass() &&
!mFramebuffer.getRenderPassRenderArea().encloses(scissoredRenderArea))
{
mFramebuffer.finishCurrentCommands(contextVk);
}
}
RenderTargetVk *FramebufferVk::getFirstRenderTarget() const
{
for (auto *renderTarget : mRenderTargetCache.getColors())
......
......@@ -105,8 +105,6 @@ class FramebufferVk : public FramebufferImpl
gl::Rectangle getCompleteRenderArea() const;
gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const;
void onScissorChange(ContextVk *contextVk);
const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const;
RenderTargetVk *getColorReadRenderTarget() const;
......
......@@ -1428,29 +1428,18 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk,
BufferVk *bufferVk = vk::GetImpl(bufferBinding.get());
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
if (isStorageBuffer)
if (contextVk->getFeatures().commandGraph.enabled)
{
// We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
if (contextVk->getFeatures().commandGraph.enabled)
if (isStorageBuffer)
{
// We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
bufferHelper.onWrite(contextVk, recorder, accessFlags);
}
else
{
contextVk->onBufferWrite(accessFlags, &bufferHelper);
}
}
else
{
if (contextVk->getFeatures().commandGraph.enabled)
{
bufferHelper.onRead(contextVk, recorder, VK_ACCESS_UNIFORM_READ_BIT);
}
else
{
contextVk->onBufferRead(VK_ACCESS_UNIFORM_READ_BIT, &bufferHelper);
}
}
++writeCount;
......
......@@ -61,15 +61,19 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
ASSERT(commandBuffer->valid());
ASSERT(!mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
commandBuffer);
if (contextVk->commandGraphEnabled())
{
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
commandBuffer);
// Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ColorAttachment, mImage));
}
onImageViewAccess(contextVk);
......@@ -83,14 +87,21 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
ASSERT(commandBuffer->valid());
ASSERT(mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = mImage->getFormat().actualImageFormat();
VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
mImage->changeLayout(aspectFlags, vk::ImageLayout::DepthStencilAttachment, commandBuffer);
if (contextVk->commandGraphEnabled())
{
mImage->changeLayout(aspectFlags, vk::ImageLayout::DepthStencilAttachment, commandBuffer);
// Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk);
// Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk);
}
else
{
ANGLE_TRY(
contextVk->onImageWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment, mImage));
}
onImageViewAccess(contextVk);
......@@ -180,7 +191,14 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
return angle::Result::Continue;
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
return mImage->flushStagedUpdates(contextVk, mLevelIndex, mLevelIndex + 1, mLayerIndex,
mLayerIndex + 1, commandBuffer);
}
......
......@@ -1086,13 +1086,23 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mColorImageMS.recordCommands(contextVk, &commandBuffer));
}
mColorImageMS.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
commandBuffer);
mColorImageMS.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
commandBuffer);
image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Setup graph dependency between the swapchain image and the multisampled one.
image.image.addReadDependency(contextVk, &mColorImageMS);
// Setup graph dependency between the swapchain image and the multisampled one.
image.image.addReadDependency(contextVk, &mColorImageMS);
ANGLE_TRY(image.image.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferSrc, &mColorImageMS));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, &image.image));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
VkImageResolve resolveRegion = {};
resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
......@@ -1104,10 +1114,6 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
resolveRegion.dstOffset = {};
resolveRegion.extent = image.image.getExtents();
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(image.image.recordCommands(contextVk, &commandBuffer));
}
mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer);
}
......
......@@ -572,12 +572,20 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
gl::Extents extents = {sourceArea.width, sourceArea.height, 1};
// Change source layout if necessary
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
if (contextVk->commandGraphEnabled())
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
}
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcImage));
}
VkImageSubresourceLayers srcSubresource = {};
......@@ -593,14 +601,23 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
// Change the image layout before the transfer
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Change the image layout before the transfer
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, mImage);
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, mImage);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, mImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
VkImageSubresourceLayers destSubresource = srcSubresource;
destSubresource.mipLevel = level;
......@@ -628,14 +645,23 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
destFormat, kTransferStagingImageFlags, layerCount));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(stagingImage->recordCommands(contextVk, &commandBuffer));
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(stagingImage->recordCommands(contextVk, &commandBuffer));
// Change the image layout before the transfer
stagingImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Change the image layout before the transfer
stagingImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, stagingImage.get());
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, stagingImage.get());
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, stagingImage.get()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
VkImageSubresourceLayers destSubresource = srcSubresource;
destSubresource.mipLevel = 0;
......@@ -1155,7 +1181,15 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
if (mImage->hasStagedUpdates())
{
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
mImage->onResourceAccess(&contextVk->getResourceUseList());
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0),
mImage->getLevelCount(), getNativeImageLayer(0),
mImage->getLayerCount(), commandBuffer));
......@@ -1168,9 +1202,13 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
// Create a new node for the image and add a global memory barrier for the staging buffer.
// It's written to and staged to be read from when ensureImageInitialized() is called.
mImage->finishCurrentCommands(contextVk);
mImage->addGlobalMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
if (contextVk->commandGraphEnabled())
{
mImage->finishCurrentCommands(contextVk);
mImage->addGlobalMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
onStagingBufferChange();
// Release the origin image and recreate it with new mipmap counts.
......
......@@ -108,15 +108,19 @@ void RendererVk::ensureCapsInitialized() const
// We use secondary command buffers almost everywhere and they require a feature to be
// able to execute in the presence of queries. As a result, we won't support queries
// unless that feature is available.
// TODO(jmadill): Enable without graph. http://anglebug.com/4029
mNativeExtensions.occlusionQueryBoolean =
vk::CommandBuffer::SupportsQueries(mPhysicalDeviceFeatures);
vk::CommandBuffer::SupportsQueries(mPhysicalDeviceFeatures) &&
mFeatures.commandGraph.enabled;
// From the Vulkan specs:
// > The number of valid bits in a timestamp value is determined by the
// > VkQueueFamilyProperties::timestampValidBits property of the queue on which the timestamp is
// > written. Timestamps are supported on any queue which reports a non-zero value for
// > timestampValidBits via vkGetPhysicalDeviceQueueFamilyProperties.
mNativeExtensions.disjointTimerQuery = queueFamilyProperties.timestampValidBits > 0;
// TODO(jmadill): Enable without graph. http://anglebug.com/4029
mNativeExtensions.disjointTimerQuery =
queueFamilyProperties.timestampValidBits > 0 && mFeatures.commandGraph.enabled;
mNativeExtensions.queryCounterBitsTimeElapsed = queueFamilyProperties.timestampValidBits;
mNativeExtensions.queryCounterBitsTimestamp = queueFamilyProperties.timestampValidBits;
......@@ -467,7 +471,8 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.pixelBufferObjectNV = true;
// Enable GL_NV_fence extension.
mNativeExtensions.fenceNV = true;
// TODO(jmadill): Enable without graph. http://anglebug.com/4029
mNativeExtensions.fenceNV = mFeatures.commandGraph.enabled;
// Geometry shader is optional.
if (mPhysicalDeviceFeatures.geometryShader)
......
......@@ -927,6 +927,9 @@ TEST_P(RobustResourceInitTest, Texture)
{
ANGLE_SKIP_TEST_IF(!hasGLExtension());
// Flaky failure on Linux / NV / Vulkan when run in a sequence. http://anglebug.com/3416
ANGLE_SKIP_TEST_IF(IsVulkan() && IsNVIDIA() && IsLinux());
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
......
......@@ -1080,6 +1080,6 @@ TEST_P(SimpleOperationTest, PrimitiveModeNegativeTest)
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(SimpleOperationTest, WithNoCommandGraph(ES2_VULKAN()));
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(SimpleOperationTest);
} // namespace
......@@ -118,7 +118,7 @@ struct CombinedPrintToStringParamName
#define ANGLE_ALL_TEST_PLATFORMS_ES2 \
ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES(), ES2_VULKAN(), ES2_VULKAN_SWIFTSHADER(), \
ES2_METAL()
ES2_METAL(), WithNoCommandGraph(ES2_VULKAN())
#define ANGLE_ALL_TEST_PLATFORMS_ES3 \
ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER()
......
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