Commit ee244c77 by Geoff Lang Committed by Commit Bot

Vulkan: Move command graph and garbage to ContextVk.

To support multithreading, contexts should manage their own command graphs and garbage. This allows safe access to vulkan resources such as command pools without thread synchronization. BUG=angleproject:2464 Change-Id: I930149bc9f0793028761ee05ab50b8c0a4dec98a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1516515 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent dfe141f0
......@@ -653,6 +653,9 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface)
FramebufferAttachment::kDefaultBaseViewIndex, false);
}
SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
// Ensure the backend has a chance to synchronize its content for a new backbuffer.
mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0);
}
Framebuffer::Framebuffer(rx::GLImplFactory *factory)
......
......@@ -35,14 +35,13 @@ BufferVk::~BufferVk() {}
void BufferVk::destroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
release(renderer);
release(contextVk);
}
void BufferVk::release(RendererVk *renderer)
void BufferVk::release(ContextVk *contextVk)
{
mBuffer.release(renderer);
mBuffer.release(contextVk);
}
angle::Result BufferVk::setData(const gl::Context *context,
......@@ -56,7 +55,7 @@ angle::Result BufferVk::setData(const gl::Context *context,
if (size > static_cast<size_t>(mState.getSize()))
{
// Release and re-create the memory and buffer.
release(contextVk->getRenderer());
release(contextVk);
// We could potentially use multiple backing buffers for different usages.
// For now keep a single buffer with all relevant usage flags.
......@@ -223,11 +222,10 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk,
size_t size,
size_t offset)
{
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = contextVk->getDevice();
// Use map when available.
if (mBuffer.isResourceInUse(renderer))
if (mBuffer.isResourceInUse(contextVk))
{
vk::StagingBuffer stagingBuffer;
ANGLE_TRY(stagingBuffer.init(contextVk, static_cast<VkDeviceSize>(size),
......@@ -247,7 +245,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk,
VK_ACCESS_HOST_WRITE_BIT, copyRegion));
// Immediately release staging buffer. We should probably be using a DynamicBuffer here.
renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingBuffer);
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &stagingBuffer);
}
else
{
......
......@@ -88,7 +88,7 @@ class BufferVk : public BufferImpl
const uint8_t *data,
size_t size,
size_t offset);
void release(RendererVk *renderer);
void release(ContextVk *context);
vk::BufferHelper mBuffer;
VkAccessFlags mDataWriteAccessFlags;
......
......@@ -26,7 +26,7 @@ namespace vk
namespace
{
ANGLE_MAYBE_UNUSED
angle::Result InitAndBeginCommandBuffer(vk::Context *context,
angle::Result InitAndBeginCommandBuffer(ContextVk *context,
const CommandPool &commandPool,
const VkCommandBufferInheritanceInfo &inheritanceInfo,
VkCommandBufferUsageFlags flags,
......@@ -177,9 +177,9 @@ CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType
CommandGraphResource::~CommandGraphResource() = default;
bool CommandGraphResource::isResourceInUse(RendererVk *renderer) const
bool CommandGraphResource::isResourceInUse(ContextVk *context) const
{
return renderer->isSerialInUse(mStoredQueueSerial);
return context->isSerialInUse(mStoredQueueSerial);
}
void CommandGraphResource::resetQueueSerial()
......@@ -189,23 +189,23 @@ void CommandGraphResource::resetQueueSerial()
mStoredQueueSerial = Serial();
}
angle::Result CommandGraphResource::recordCommands(Context *context,
angle::Result CommandGraphResource::recordCommands(ContextVk *context,
CommandBuffer **commandBufferOut)
{
updateQueueSerial(context->getRenderer()->getCurrentQueueSerial());
updateQueueSerial(context->getCurrentQueueSerial());
if (!hasChildlessWritingNode() || hasStartedRenderPass())
{
startNewCommands(context->getRenderer());
startNewCommands(context);
return mCurrentWritingNode->beginOutsideRenderPassRecording(
context, context->getRenderer()->getCommandPool(), commandBufferOut);
context, context->getCommandPool(), commandBufferOut);
}
CommandBuffer *outsideRenderPassCommands = mCurrentWritingNode->getOutsideRenderPassCommands();
if (!outsideRenderPassCommands->valid())
{
ANGLE_TRY(mCurrentWritingNode->beginOutsideRenderPassRecording(
context, context->getRenderer()->getCommandPool(), commandBufferOut));
context, context->getCommandPool(), commandBufferOut));
}
else
{
......@@ -227,7 +227,7 @@ angle::Result CommandGraphResource::beginRenderPass(
// If a barrier has been inserted in the meantime, stop the command buffer.
if (!hasChildlessWritingNode())
{
startNewCommands(contextVk->getRenderer());
startNewCommands(contextVk);
}
mCurrentWritingNode->storeRenderPassInfo(framebuffer, renderArea, renderPassDesc,
......@@ -263,17 +263,17 @@ void CommandGraphResource::addReadDependency(CommandGraphResource *readingResour
mCurrentReadingNodes.push_back(readingNode);
}
void CommandGraphResource::finishCurrentCommands(RendererVk *renderer)
void CommandGraphResource::finishCurrentCommands(ContextVk *contextVk)
{
startNewCommands(renderer);
startNewCommands(contextVk);
}
void CommandGraphResource::startNewCommands(RendererVk *renderer)
void CommandGraphResource::startNewCommands(ContextVk *contextVk)
{
CommandGraphNode *newCommands =
renderer->getCommandGraph()->allocateNode(CommandGraphNodeFunction::Generic);
contextVk->getCommandGraph()->allocateNode(CommandGraphNodeFunction::Generic);
newCommands->setDiagnosticInfo(mResourceType, reinterpret_cast<uintptr_t>(this));
onWriteImpl(newCommands, renderer->getCurrentQueueSerial());
onWriteImpl(newCommands, contextVk->getCurrentQueueSerial());
}
void CommandGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
......@@ -320,7 +320,7 @@ CommandGraphNode::~CommandGraphNode()
mInsideRenderPassCommands.releaseHandle();
}
angle::Result CommandGraphNode::beginOutsideRenderPassRecording(Context *context,
angle::Result CommandGraphNode::beginOutsideRenderPassRecording(ContextVk *context,
const CommandPool &commandPool,
CommandBuffer **commandsOut)
{
......@@ -343,7 +343,7 @@ angle::Result CommandGraphNode::beginOutsideRenderPassRecording(Context *context
return angle::Result::Continue;
}
angle::Result CommandGraphNode::beginInsideRenderPassRecording(Context *context,
angle::Result CommandGraphNode::beginInsideRenderPassRecording(ContextVk *context,
CommandBuffer **commandsOut)
{
ASSERT(!mHasChildren);
......@@ -351,8 +351,7 @@ angle::Result CommandGraphNode::beginInsideRenderPassRecording(Context *context,
// Get a compatible RenderPass from the cache so we can initialize the inheritance info.
// TODO(jmadill): Support query for compatible/conformant render pass. http://anglebug.com/2361
RenderPass *compatibleRenderPass;
ANGLE_TRY(context->getRenderer()->getCompatibleRenderPass(context, mRenderPassDesc,
&compatibleRenderPass));
ANGLE_TRY(context->getCompatibleRenderPass(mRenderPassDesc, &compatibleRenderPass));
VkCommandBufferInheritanceInfo inheritanceInfo = {};
inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
......@@ -364,8 +363,7 @@ angle::Result CommandGraphNode::beginInsideRenderPassRecording(Context *context,
inheritanceInfo.queryFlags = 0;
inheritanceInfo.pipelineStatistics = 0;
ANGLE_TRY(InitAndBeginCommandBuffer(context, context->getRenderer()->getCommandPool(),
inheritanceInfo,
ANGLE_TRY(InitAndBeginCommandBuffer(context, context->getCommandPool(), inheritanceInfo,
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
mPoolAllocator, &mInsideRenderPassCommands));
......@@ -708,7 +706,7 @@ void CommandGraph::setNewBarrier(CommandGraphNode *newBarrier)
mLastBarrierIndex = mNodes.size() - 1;
}
angle::Result CommandGraph::submitCommands(Context *context,
angle::Result CommandGraph::submitCommands(ContextVk *context,
Serial serial,
RenderPassCache *renderPassCache,
CommandPool *commandPool,
......@@ -751,8 +749,8 @@ angle::Result CommandGraph::submitCommands(Context *context,
ANGLE_VK_TRY(context, primaryCommandBufferOut->begin(beginInfo));
ANGLE_TRY(context->getRenderer()->traceGpuEvent(
context, primaryCommandBufferOut, TRACE_EVENT_PHASE_BEGIN, "Primary Command Buffer"));
ANGLE_TRY(context->traceGpuEvent(primaryCommandBufferOut, TRACE_EVENT_PHASE_BEGIN,
"Primary Command Buffer"));
for (CommandGraphNode *topLevelNode : mNodes)
{
......@@ -787,8 +785,8 @@ angle::Result CommandGraph::submitCommands(Context *context,
}
}
ANGLE_TRY(context->getRenderer()->traceGpuEvent(
context, primaryCommandBufferOut, TRACE_EVENT_PHASE_END, "Primary Command Buffer"));
ANGLE_TRY(context->traceGpuEvent(primaryCommandBufferOut, TRACE_EVENT_PHASE_END,
"Primary Command Buffer"));
ANGLE_VK_TRY(context, primaryCommandBufferOut->end());
......
......@@ -87,12 +87,12 @@ class CommandGraphNode final : angle::NonCopyable
}
// For outside the render pass (copies, transitions, etc).
angle::Result beginOutsideRenderPassRecording(Context *context,
angle::Result beginOutsideRenderPassRecording(ContextVk *context,
const CommandPool &commandPool,
CommandBuffer **commandsOut);
// For rendering commands (draws).
angle::Result beginInsideRenderPassRecording(Context *context, CommandBuffer **commandsOut);
angle::Result beginInsideRenderPassRecording(ContextVk *context, CommandBuffer **commandsOut);
// storeRenderPassInfo and append*RenderTarget store info relevant to the RenderPass.
void storeRenderPassInfo(const Framebuffer &framebuffer,
......@@ -251,7 +251,7 @@ class CommandGraphResource : angle::NonCopyable
virtual ~CommandGraphResource();
// Returns true if the resource is in use by the renderer.
bool isResourceInUse(RendererVk *renderer) const;
bool isResourceInUse(ContextVk *context) const;
// Get the current queue serial for this resource. Used to release resources, and for
// queries, to know if the queue they are submitted on has finished execution.
......@@ -284,7 +284,7 @@ class CommandGraphResource : angle::NonCopyable
// Allocates a write node via getNewWriteNode and returns a started command buffer.
// The started command buffer will render outside of a RenderPass.
// Will append to an existing command buffer/graph node if possible.
angle::Result recordCommands(Context *context, CommandBuffer **commandBufferOut);
angle::Result recordCommands(ContextVk *context, CommandBuffer **commandBufferOut);
// Begins a command buffer on the current graph node for in-RenderPass rendering.
// Called from FramebufferVk::startNewRenderPass and UtilsVk functions.
......@@ -356,7 +356,7 @@ class CommandGraphResource : angle::NonCopyable
}
// Called when 'this' object changes, but we'd like to start a new command buffer later.
void finishCurrentCommands(RendererVk *renderer);
void finishCurrentCommands(ContextVk *contextVk);
// Store a deferred memory barrier. Will be recorded into a primary command buffer at submit.
void addGlobalMemoryBarrier(VkFlags srcAccess, VkFlags dstAccess)
......@@ -382,7 +382,7 @@ class CommandGraphResource : angle::NonCopyable
return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren());
}
void startNewCommands(RendererVk *renderer);
void startNewCommands(ContextVk *contextVk);
void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial);
......@@ -430,7 +430,7 @@ class CommandGraph final : angle::NonCopyable
// dependencies between the previous barrier, the new barrier and all nodes in between.
CommandGraphNode *allocateNode(CommandGraphNodeFunction function);
angle::Result submitCommands(Context *context,
angle::Result submitCommands(ContextVk *context,
Serial serial,
RenderPassCache *renderPassCache,
CommandPool *commandPool,
......
......@@ -39,9 +39,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
// Flush and finish.
angle::Result flush(const gl::Context *context) override;
angle::Result flushImpl();
angle::Result finish(const gl::Context *context) override;
angle::Result finishImpl();
// Drawing methods.
angle::Result drawArrays(const gl::Context *context,
......@@ -220,6 +218,72 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void setIndexBufferDirty() { mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); }
angle::Result flushImpl();
angle::Result finishImpl();
const vk::CommandPool &getCommandPool() const;
Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; }
Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; }
bool isSerialInUse(Serial serial) const;
template <typename T>
void releaseObject(Serial resourceSerial, T *object)
{
if (!isSerialInUse(resourceSerial))
{
object->destroy(getDevice());
}
else
{
object->dumpResources(resourceSerial, &mGarbage);
}
}
// Check to see which batches have finished completion (forward progress for
// mLastCompletedQueueSerial, for example for when the application busy waits on a query
// result).
angle::Result checkCompletedCommands();
// Wait for completion of batches until (at least) batch with given serial is finished.
angle::Result finishToSerial(Serial serial);
// A variant of finishToSerial that can time out. Timeout status returned in outTimedOut.
angle::Result finishToSerialOrTimeout(Serial serial, uint64_t timeout, bool *outTimedOut);
angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
vk::RenderPass **renderPassOut);
angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
const vk::AttachmentOpsArray &ops,
vk::RenderPass **renderPassOut);
// Get (or allocate) the fence that will be signaled on next submission.
angle::Result getSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut);
vk::Shared<vk::Fence> getLastSubmittedFence() const;
// This should only be called from ResourceVk.
vk::CommandGraph *getCommandGraph();
vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
UtilsVk &getUtils() { return mUtils; }
angle::Result getTimestamp(uint64_t *timestampOut);
// Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
// The events are queued until the query results are available. Possible values for `phase`
// are TRACE_EVENT_PHASE_*
ANGLE_INLINE angle::Result traceGpuEvent(vk::PrimaryCommandBuffer *commandBuffer,
char phase,
const char *name)
{
if (mGpuEventsEnabled)
return traceGpuEventImpl(commandBuffer, phase, name);
return angle::Result::Continue;
}
RenderPassCache &getRenderPassCache() { return mRenderPassCache; }
private:
// Dirty bits.
enum DirtyBitType : size_t
......@@ -300,6 +364,21 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
angle::Result handleDirtyDescriptorSets(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
angle::Result submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer);
void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch);
angle::Result synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphore,
const vk::Semaphore *signalSemaphore);
angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer,
char phase,
const char *name);
angle::Result checkCompletedGpuEvents();
void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
void handleDeviceLost();
vk::PipelineHelper *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode;
......@@ -372,6 +451,100 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
// "Current Value" aka default vertex attribute state.
gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
vk::CommandPool mCommandPool;
Serial mLastCompletedQueueSerial;
Serial mLastSubmittedQueueSerial;
Serial mCurrentQueueSerial;
struct CommandBatch final : angle::NonCopyable
{
CommandBatch();
~CommandBatch();
CommandBatch(CommandBatch &&other);
CommandBatch &operator=(CommandBatch &&other);
void destroy(VkDevice device);
vk::CommandPool commandPool;
vk::Shared<vk::Fence> fence;
Serial serial;
};
std::vector<CommandBatch> mInFlightCommands;
std::vector<vk::GarbageObject> mGarbage;
RenderPassCache mRenderPassCache;
// mSubmitFence is the fence that's going to be signaled at the next submission. This is used
// to support SyncVk objects, which may outlive the context (as EGLSync objects).
//
// TODO(geofflang): this is in preparation for moving RendererVk functionality to ContextVk, and
// is otherwise unnecessary as the SyncVk objects don't actually outlive the renderer currently.
// http://anglebug.com/2701
vk::Shared<vk::Fence> mSubmitFence;
// Pool allocator used for command graph but may be expanded to other allocations
angle::PoolAllocator mPoolAllocator;
// See CommandGraph.h for a desription of the Command Graph.
vk::CommandGraph mCommandGraph;
// Internal shader library.
vk::ShaderLibrary mShaderLibrary;
UtilsVk mUtils;
// The GpuEventQuery struct holds together a timestamp query and enough data to create a
// trace event based on that. Use traceGpuEvent to insert such queries. They will be readback
// when the results are available, without inserting a GPU bubble.
//
// - eventName will be the reported name of the event
// - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
// See Google's "Trace Event Format":
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
// - serial is the serial of the batch the query was submitted on. Until the batch is
// submitted, the query is not checked to avoid incuring a flush.
struct GpuEventQuery final
{
const char *name;
char phase;
uint32_t queryIndex;
size_t queryPoolIndex;
Serial serial;
};
// Once a query result is available, the timestamp is read and a GpuEvent object is kept until
// the next clock sync, at which point the clock drift is compensated in the results before
// handing them off to the application.
struct GpuEvent final
{
uint64_t gpuTimestampCycles;
const char *name;
char phase;
};
bool mGpuEventsEnabled;
vk::DynamicQueryPool mGpuEventQueryPool;
// A list of queries that have yet to be turned into an event (their result is not yet
// available).
std::vector<GpuEventQuery> mInFlightGpuEventQueries;
// A list of gpu events since the last clock sync.
std::vector<GpuEvent> mGpuEvents;
// Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
struct GpuClockSyncInfo
{
double gpuTimestampS;
double cpuTimestampS;
};
GpuClockSyncInfo mGpuClockSync;
// The very first timestamp queried for a GPU event is used as origin, so event timestamps would
// have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
// double.
uint64_t mGpuEventTimestampOrigin;
};
} // namespace rx
......
......@@ -156,11 +156,10 @@ FramebufferVk::~FramebufferVk() = default;
void FramebufferVk::destroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mFramebuffer.release(renderer);
mFramebuffer.release(contextVk);
mReadPixelBuffer.release(renderer);
mBlitPixelBuffer.release(renderer);
mReadPixelBuffer.release(contextVk);
mBlitPixelBuffer.release(contextVk);
}
angle::Result FramebufferVk::discard(const gl::Context *context,
......@@ -226,7 +225,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
return angle::Result::Continue;
}
mFramebuffer.updateQueueSerial(contextVk->getRenderer()->getCurrentQueueSerial());
mFramebuffer.updateQueueSerial(contextVk->getCurrentQueueSerial());
// This function assumes that only enabled attachments are asked to be cleared.
ASSERT((clearColorBuffers & mState.getEnabledDrawBuffers()) == clearColorBuffers);
......@@ -297,7 +296,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
// that case, end the render pass immediately. http://anglebug.com/2361
if (contextVk->getRenderer()->getFeatures().restartRenderPassAfterLoadOpClear.enabled)
{
mFramebuffer.finishCurrentCommands(contextVk->getRenderer());
mFramebuffer.finishCurrentCommands(contextVk);
}
// Fallback to other methods for whatever isn't cleared here.
......@@ -440,7 +439,6 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
const gl::Extents &fbSize = getState().getReadAttachment()->getSize();
const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
gl::Rectangle clippedArea;
if (!ClipRectangle(area, fbRect, &clippedArea))
......@@ -482,7 +480,7 @@ angle::Result FramebufferVk::readPixels(const gl::Context *context,
ANGLE_TRY(readPixelsImpl(contextVk, flippedArea, params, VK_IMAGE_ASPECT_COLOR_BIT,
getColorReadRenderTarget(),
static_cast<uint8_t *>(pixels) + outputSkipBytes));
mReadPixelBuffer.releaseRetainedBuffers(renderer);
mReadPixelBuffer.releaseRetainedBuffers(contextVk);
return angle::Result::Continue;
}
......@@ -538,7 +536,6 @@ angle::Result FramebufferVk::blitWithReadback(ContextVk *contextVk,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget)
{
RendererVk *renderer = contextVk->getRenderer();
const angle::Format &readFormat = readRenderTarget->getImageFormat().imageFormat();
ASSERT(aspect == VK_IMAGE_ASPECT_DEPTH_BIT || aspect == VK_IMAGE_ASPECT_STENCIL_BIT);
......@@ -599,7 +596,7 @@ angle::Result FramebufferVk::blitWithReadback(ContextVk *contextVk,
commandBuffer->copyBufferToImage(destBufferHandle, imageForWrite->getImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copyRegion);
mBlitPixelBuffer.releaseRetainedBuffers(renderer);
mBlitPixelBuffer.releaseRetainedBuffers(contextVk);
return angle::Result::Continue;
}
......@@ -843,7 +840,6 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
ASSERT(dirtyBits.any());
for (size_t dirtyBit : dirtyBits)
......@@ -892,11 +888,11 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
mActiveColorComponentMasksForClear[0].any(), mActiveColorComponentMasksForClear[1].any(),
mActiveColorComponentMasksForClear[2].any(), mActiveColorComponentMasksForClear[3].any());
mFramebuffer.release(renderer);
mFramebuffer.release(contextVk);
// Will freeze the current set of dependencies on this FBO. The next time we render we will
// create a new entry in the command graph.
mFramebuffer.finishCurrentCommands(renderer);
mFramebuffer.finishCurrentCommands(contextVk);
// Notify the ContextVk to update the pipeline desc.
updateRenderPassDesc();
......@@ -945,8 +941,7 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
}
vk::RenderPass *compatibleRenderPass = nullptr;
ANGLE_TRY(contextVk->getRenderer()->getCompatibleRenderPass(contextVk, mRenderPassDesc,
&compatibleRenderPass));
ANGLE_TRY(contextVk->getCompatibleRenderPass(mRenderPassDesc, &compatibleRenderPass));
// If we've a Framebuffer provided by a Surface (default FBO/backbuffer), query it.
if (mBackbuffer)
......@@ -1072,8 +1067,6 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
const VkClearColorValue &clearColorValue,
uint8_t clearStencilValue)
{
RendererVk *renderer = contextVk->getRenderer();
UtilsVk::ClearFramebufferParameters params = {};
params.renderPassDesc = &getRenderPassDesc();
params.renderAreaHeight = mState.getDimensions().height;
......@@ -1099,7 +1092,7 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
params.colorMaskFlags &= ~VK_COLOR_COMPONENT_A_BIT;
}
ANGLE_TRY(renderer->getUtils().clearFramebuffer(contextVk, this, params));
ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params));
// Clear stencil only once!
params.clearStencil = false;
......@@ -1109,7 +1102,7 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
if (params.clearStencil)
{
params.clearColor = false;
ANGLE_TRY(renderer->getUtils().clearFramebuffer(contextVk, this, params));
ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params));
}
return angle::Result::Continue;
......@@ -1222,7 +1215,7 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
contextVk, renderer->getMemoryProperties(), gl::Extents(area.width, area.height, 1),
srcImage->getFormat(),
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1));
resolvedImage.get().updateQueueSerial(renderer->getCurrentQueueSerial());
resolvedImage.get().updateQueueSerial(contextVk->getCurrentQueueSerial());
// TODO(syoussefi): resolve only works on color images (not depth/stencil). If readback
// on multisampled depth/stencil image is done, we would need a different path. One
......@@ -1328,11 +1321,11 @@ void FramebufferVk::onScissorChange(ContextVk *contextVk)
// 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.updateQueueSerial(contextVk->getRenderer()->getCurrentQueueSerial());
mFramebuffer.updateQueueSerial(contextVk->getCurrentQueueSerial());
if (mFramebuffer.hasStartedRenderPass() &&
!mFramebuffer.getRenderPassRenderArea().encloses(scissoredRenderArea))
{
mFramebuffer.finishCurrentCommands(contextVk->getRenderer());
mFramebuffer.finishCurrentCommands(contextVk);
}
}
......
......@@ -157,7 +157,7 @@ angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sib
// Flush the context to make sure the fence has been submitted.
ANGLE_TRY(contextVk->flushImpl());
vk::Shared<vk::Fence> fence = contextVk->getRenderer()->getLastSubmittedFence();
vk::Shared<vk::Fence> fence = contextVk->getLastSubmittedFence();
if (fence.isReferenced())
{
mImageLastUseFences.push_back(std::move(fence));
......
......@@ -120,7 +120,7 @@ angle::Result SyncDefaultUniformBlock(ContextVk *contextVk,
uint32_t *outOffset,
bool *outBufferModified)
{
dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
dynamicBuffer->releaseRetainedBuffers(contextVk);
ASSERT(!bufferData.empty());
uint8_t *data = nullptr;
......@@ -202,13 +202,13 @@ angle::Result ProgramVk::ShaderInfo::initShaders(ContextVk *contextVk,
return angle::Result::Continue;
}
void ProgramVk::ShaderInfo::release(RendererVk *renderer)
void ProgramVk::ShaderInfo::release(ContextVk *contextVk)
{
mProgramHelper.release(renderer);
mProgramHelper.release(contextVk);
for (vk::RefCounted<vk::ShaderAndSerial> &shader : mShaders)
{
shader.get().destroy(renderer->getDevice());
shader.get().destroy(contextVk->getDevice());
}
}
......@@ -228,10 +228,10 @@ ProgramVk::~ProgramVk() = default;
void ProgramVk::destroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
reset(contextVk->getRenderer());
reset(contextVk);
}
void ProgramVk::reset(RendererVk *renderer)
void ProgramVk::reset(ContextVk *contextVk)
{
for (auto &descriptorSetLayout : mDescriptorSetLayouts)
{
......@@ -241,13 +241,13 @@ void ProgramVk::reset(RendererVk *renderer)
for (auto &uniformBlock : mDefaultUniformBlocks)
{
uniformBlock.storage.release(renderer);
uniformBlock.storage.release(contextVk);
}
mDefaultShaderInfo.release(renderer);
mLineRasterShaderInfo.release(renderer);
mDefaultShaderInfo.release(contextVk);
mLineRasterShaderInfo.release(contextVk);
mEmptyUniformBlockStorage.release(renderer);
mEmptyUniformBlockStorage.release(contextVk);
mDescriptorSets.clear();
mEmptyDescriptorSets.fill(VK_NULL_HANDLE);
......@@ -297,7 +297,7 @@ angle::Result ProgramVk::linkImpl(const gl::Context *glContext,
ContextVk *contextVk = vk::GetImpl(glContext);
RendererVk *renderer = contextVk->getRenderer();
reset(renderer);
reset(contextVk);
// Link resources before calling GetShaderSource to make sure they are ready for the set/binding
// assignment done in that function.
......
......@@ -134,8 +134,8 @@ class ProgramVk : public ProgramImpl
ASSERT(shaderProgram->isGraphicsProgram());
RendererVk *renderer = contextVk->getRenderer();
return shaderProgram->getGraphicsPipeline(
contextVk, &renderer->getRenderPassCache(), renderer->getPipelineCache(),
renderer->getCurrentQueueSerial(), mPipelineLayout.get(), desc, activeAttribLocations,
contextVk, &contextVk->getRenderPassCache(), renderer->getPipelineCache(),
contextVk->getCurrentQueueSerial(), mPipelineLayout.get(), desc, activeAttribLocations,
descPtrOut, pipelineOut);
}
......@@ -146,7 +146,7 @@ class ProgramVk : public ProgramImpl
GLboolean transpose,
const GLfloat *value);
void reset(RendererVk *renderer);
void reset(ContextVk *contextVk);
angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
......@@ -240,7 +240,7 @@ class ProgramVk : public ProgramImpl
const std::string &vertexSource,
const std::string &fragmentSource,
bool enableLineRasterEmulation);
void release(RendererVk *renderer);
void release(ContextVk *contextVk);
ANGLE_INLINE bool valid() const { return mShaders[gl::ShaderType::Vertex].get().valid(); }
......
......@@ -108,25 +108,25 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
// finite time.
// Note regarding time-elapsed: end should have been called after begin, so flushing when end
// has pending work should flush begin too.
if (mQueryHelper.hasPendingWork(renderer))
if (mQueryHelper.hasPendingWork(contextVk))
{
ANGLE_TRY(contextVk->flushImpl());
ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(renderer));
ASSERT(!mQueryHelper.hasPendingWork(renderer));
ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(contextVk));
ASSERT(!mQueryHelper.hasPendingWork(contextVk));
}
// If the command buffer this query is being written to is still in flight, its reset command
// may not have been performed by the GPU yet. To avoid a race condition in this case, wait
// for the batch to finish first before querying (or return not-ready if not waiting).
ANGLE_TRY(renderer->checkCompletedCommands(contextVk));
if (renderer->isSerialInUse(mQueryHelper.getStoredQueueSerial()))
ANGLE_TRY(contextVk->checkCompletedCommands());
if (contextVk->isSerialInUse(mQueryHelper.getStoredQueueSerial()))
{
if (!wait)
{
return angle::Result::Continue;
}
ANGLE_TRY(renderer->finishToSerial(contextVk, mQueryHelper.getStoredQueueSerial()));
ANGLE_TRY(contextVk->finishToSerial(mQueryHelper.getStoredQueueSerial()));
}
VkQueryResultFlags flags = (wait ? VK_QUERY_RESULT_WAIT_BIT : 0) | VK_QUERY_RESULT_64_BIT;
......
......@@ -26,8 +26,7 @@ RenderbufferVk::~RenderbufferVk() {}
void RenderbufferVk::onDestroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
releaseAndDeleteImage(contextVk);
}
angle::Result RenderbufferVk::setStorage(const gl::Context *context,
......@@ -41,7 +40,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
if (!mOwnsImage)
{
releaseAndDeleteImage(context, renderer);
releaseAndDeleteImage(contextVk);
}
if (mImage != nullptr && mImage->valid())
......@@ -51,7 +50,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
static_cast<GLsizei>(width) != mState.getWidth() ||
static_cast<GLsizei>(height) != mState.getHeight())
{
releaseImage(context, renderer);
releaseImage(contextVk);
}
}
......@@ -85,7 +84,7 @@ angle::Result RenderbufferVk::setStorage(const gl::Context *context,
&mImageView, 0, 1));
// Clear the renderbuffer if it has emulated channels.
mImage->clearIfEmulatedFormat(vk::GetImpl(context), gl::ImageIndex::Make2D(0), vkFormat);
mImage->stageClearIfEmulatedFormat(gl::ImageIndex::Make2D(0), vkFormat);
mRenderTarget.init(mImage, &mImageView, nullptr, 0, 0);
}
......@@ -109,7 +108,7 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
releaseAndDeleteImage(context, renderer);
releaseAndDeleteImage(contextVk);
ImageVk *imageVk = vk::GetImpl(image);
mImage = imageVk->getImage();
......@@ -172,32 +171,31 @@ angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mOwnsImage = false;
releaseAndDeleteImage(context, renderer);
releaseAndDeleteImage(contextVk);
}
void RenderbufferVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
void RenderbufferVk::releaseAndDeleteImage(ContextVk *contextVk)
{
releaseImage(context, renderer);
releaseImage(contextVk);
SafeDelete(mImage);
}
void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *renderer)
void RenderbufferVk::releaseImage(ContextVk *contextVk)
{
if (mImage && mOwnsImage)
{
mImage->releaseImage(renderer);
mImage->releaseStagingBuffer(renderer);
mImage->releaseImage(contextVk);
mImage->releaseStagingBuffer(contextVk);
}
else
{
mImage = nullptr;
}
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mCubeImageFetchView);
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mImageView);
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mCubeImageFetchView);
}
} // namespace rx
......@@ -48,8 +48,8 @@ class RenderbufferVk : public RenderbufferImpl
void releaseOwnershipOfImage(const gl::Context *context);
private:
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
void releaseImage(const gl::Context *context, RendererVk *renderer);
void releaseAndDeleteImage(ContextVk *contextVk);
void releaseImage(ContextVk *contextVk);
bool mOwnsImage;
vk::ImageHelper *mImage;
......
......@@ -22,10 +22,7 @@ SemaphoreVk::~SemaphoreVk() = default;
void SemaphoreVk::onDestroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
Serial currentSerial = renderer->getCurrentQueueSerial();
renderer->releaseObject(currentSerial, &mSemaphore);
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mSemaphore);
}
angle::Result SemaphoreVk::importFd(gl::Context *context, gl::HandleType handleType, GLint fd)
......
......@@ -156,19 +156,24 @@ class WindowSurfaceVk : public SurfaceVk
virtual angle::Result getCurrentWindowSize(vk::Context *context, gl::Extents *extentsOut) = 0;
angle::Result initializeImpl(DisplayVk *displayVk);
angle::Result recreateSwapchain(DisplayVk *displayVk,
angle::Result recreateSwapchain(ContextVk *contextVk,
const gl::Extents &extents,
uint32_t swapHistoryIndex);
angle::Result checkForOutOfDateSwapchain(DisplayVk *displayVk,
angle::Result createSwapChain(vk::Context *context,
const gl::Extents &extents,
VkSwapchainKHR oldSwapchain);
angle::Result checkForOutOfDateSwapchain(ContextVk *contextVk,
uint32_t swapHistoryIndex,
bool presentOutOfDate);
void releaseSwapchainImages(RendererVk *renderer);
angle::Result nextSwapchainImage(DisplayVk *displayVk);
angle::Result present(DisplayVk *displayVk,
void releaseSwapchainImages(ContextVk *contextVk);
void destroySwapChainImages(DisplayVk *displayVk);
angle::Result nextSwapchainImage(vk::Context *context);
angle::Result present(ContextVk *contextVk,
EGLint *rects,
EGLint n_rects,
bool &swapchainOutOfDate);
angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects);
angle::Result swapImpl(const gl::Context *context, EGLint *rects, EGLint n_rects);
bool isMultiSampled() const;
......@@ -228,7 +233,7 @@ class WindowSurfaceVk : public SurfaceVk
void destroy(VkDevice device);
angle::Result waitFence(DisplayVk *displayVk);
angle::Result waitFence(ContextVk *contextVk);
// Fence associated with the last submitted work to render to this swapchain image.
vk::Shared<vk::Fence> sharedFence;
......
......@@ -21,14 +21,14 @@ FenceSyncVk::FenceSyncVk() {}
FenceSyncVk::~FenceSyncVk() {}
void FenceSyncVk::onDestroy(RendererVk *renderer)
void FenceSyncVk::onDestroy(ContextVk *contextVk)
{
if (mEvent.valid())
{
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mEvent);
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mEvent);
}
mFence.reset(renderer->getDevice());
mFence.reset(contextVk->getDevice());
}
void FenceSyncVk::onDestroy(DisplayVk *display)
......@@ -53,11 +53,11 @@ angle::Result FenceSyncVk::initialize(ContextVk *contextVk)
vk::Scoped<vk::Event> event(device);
ANGLE_VK_TRY(contextVk, event.get().init(device, eventCreateInfo));
ANGLE_TRY(renderer->getSubmitFence(contextVk, &mFence));
ANGLE_TRY(contextVk->getSubmitFence(&mFence));
mEvent = event.release();
renderer->getCommandGraph()->setFenceSync(mEvent);
contextVk->getCommandGraph()->setFenceSync(mEvent);
return angle::Result::Continue;
}
......@@ -106,13 +106,16 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context,
angle::Result FenceSyncVk::serverWait(vk::Context *context, ContextVk *contextVk)
{
context->getRenderer()->getCommandGraph()->waitFenceSync(mEvent);
if (contextVk)
{
contextVk->getCommandGraph()->waitFenceSync(mEvent);
}
return angle::Result::Continue;
}
angle::Result FenceSyncVk::getStatus(vk::Context *context, bool *signaled)
{
VkResult result = mEvent.getStatus(context->getRenderer()->getDevice());
VkResult result = mEvent.getStatus(context->getDevice());
if (result != VK_EVENT_SET && result != VK_EVENT_RESET)
{
ANGLE_VK_TRY(context, result);
......@@ -127,7 +130,7 @@ SyncVk::~SyncVk() {}
void SyncVk::onDestroy(const gl::Context *context)
{
mFenceSync.onDestroy(vk::GetImpl(context)->getRenderer());
mFenceSync.onDestroy(vk::GetImpl(context));
}
angle::Result SyncVk::set(const gl::Context *context, GLenum condition, GLbitfield flags)
......@@ -201,7 +204,7 @@ EGLSyncVk::~EGLSyncVk() {}
void EGLSyncVk::onDestroy(const egl::Display *display)
{
mFenceSync.onDestroy(vk::GetImpl(display)->getRenderer());
mFenceSync.onDestroy(vk::GetImpl(display));
}
egl::Error EGLSyncVk::initialize(const egl::Display *display,
......
......@@ -30,7 +30,7 @@ class FenceSyncVk
FenceSyncVk();
~FenceSyncVk();
void onDestroy(RendererVk *renderer);
void onDestroy(ContextVk *contextVk);
void onDestroy(DisplayVk *display);
angle::Result initialize(ContextVk *contextVk);
......
......@@ -170,16 +170,16 @@ class TextureVk : public TextureImpl
uint32_t getNativeImageLevel(uint32_t frontendLevel) const;
uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
void releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer);
angle::Result ensureImageAllocated(RendererVk *renderer, const vk::Format &format);
void setImageHelper(RendererVk *renderer,
void releaseAndDeleteImage(ContextVk *context);
angle::Result ensureImageAllocated(ContextVk *context, const vk::Format &format);
void setImageHelper(ContextVk *context,
vk::ImageHelper *imageHelper,
gl::TextureType imageType,
const vk::Format &format,
uint32_t imageLevelOffset,
uint32_t imageLayerOffset,
bool selfOwned);
void updateImageHelper(RendererVk *renderer, const vk::Format &internalFormat);
void updateImageHelper(ContextVk *context, const vk::Format &internalFormat);
angle::Result redefineImage(const gl::Context *context,
const gl::ImageIndex &index,
......@@ -264,8 +264,8 @@ class TextureVk : public TextureImpl
const gl::Extents &extents,
const uint32_t levelCount,
vk::CommandBuffer *commandBuffer);
void releaseImage(RendererVk *renderer);
void releaseStagingBuffer(RendererVk *renderer);
void releaseImage(ContextVk *context);
void releaseStagingBuffer(ContextVk *context);
uint32_t getLevelCount() const;
angle::Result initImageViews(ContextVk *contextVk,
const vk::Format &format,
......
......@@ -96,14 +96,14 @@ class UtilsVk : angle::NonCopyable
bool destFlipY;
};
angle::Result clearBuffer(vk::Context *context,
angle::Result clearBuffer(ContextVk *context,
vk::BufferHelper *dest,
const ClearParameters &params);
angle::Result copyBuffer(vk::Context *context,
angle::Result copyBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const CopyParameters &params);
angle::Result convertVertexBuffer(vk::Context *context,
angle::Result convertVertexBuffer(ContextVk *context,
vk::BufferHelper *dest,
vk::BufferHelper *src,
const ConvertVertexParameters &params);
......@@ -194,7 +194,7 @@ class UtilsVk : angle::NonCopyable
// compute shader, vsShader and pipelineDesc should be nullptr, and this will set up a dispatch
// call. Otherwise fsCsShader is expected to be a fragment shader and this will set up a draw
// call.
angle::Result setupProgram(vk::Context *context,
angle::Result setupProgram(ContextVk *context,
Function function,
vk::RefCounted<vk::ShaderAndSerial> *fsCsShader,
vk::RefCounted<vk::ShaderAndSerial> *vsShader,
......@@ -210,7 +210,7 @@ class UtilsVk : angle::NonCopyable
// this array has two entries {STORAGE_TEXEL_BUFFER, 1} and {UNIFORM_TEXEL_BUFFER, 3}, then the
// created set layout would be binding 0 for storage texel buffer and bindings 1 through 3 for
// uniform texel buffer. All resources are put in set 0.
angle::Result ensureResourcesInitialized(vk::Context *context,
angle::Result ensureResourcesInitialized(ContextVk *context,
Function function,
VkDescriptorPoolSize *setSizes,
size_t setSizesCount,
......@@ -218,11 +218,11 @@ class UtilsVk : angle::NonCopyable
// Initializers corresponding to functions, calling into ensureResourcesInitialized with the
// appropriate parameters.
angle::Result ensureBufferClearResourcesInitialized(vk::Context *context);
angle::Result ensureBufferCopyResourcesInitialized(vk::Context *context);
angle::Result ensureConvertVertexResourcesInitialized(vk::Context *context);
angle::Result ensureImageClearResourcesInitialized(vk::Context *context);
angle::Result ensureImageCopyResourcesInitialized(vk::Context *context);
angle::Result ensureBufferClearResourcesInitialized(ContextVk *context);
angle::Result ensureBufferCopyResourcesInitialized(ContextVk *context);
angle::Result ensureConvertVertexResourcesInitialized(ContextVk *context);
angle::Result ensureImageClearResourcesInitialized(ContextVk *context);
angle::Result ensureImageCopyResourcesInitialized(ContextVk *context);
angle::Result startRenderPass(ContextVk *contextVk,
vk::ImageHelper *image,
......
......@@ -153,18 +153,18 @@ VertexArrayVk::~VertexArrayVk() {}
void VertexArrayVk::destroy(const gl::Context *context)
{
RendererVk *renderer = vk::GetImpl(context)->getRenderer();
ContextVk *contextVk = vk::GetImpl(context);
mTheNullBuffer.release(renderer);
mTheNullBuffer.release(contextVk);
for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
{
buffer.release(renderer);
buffer.release(contextVk);
}
mDynamicVertexData.release(renderer);
mDynamicIndexData.release(renderer);
mTranslatedByteIndexData.release(renderer);
mLineLoopHelper.release(renderer);
mDynamicVertexData.release(contextVk);
mDynamicIndexData.release(contextVk);
mTranslatedByteIndexData.release(contextVk);
mLineLoopHelper.release(contextVk);
}
angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
......@@ -175,7 +175,7 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
{
ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
dynamicBuffer->releaseRetainedBuffers(contextVk);
const size_t amount = sizeof(GLushort) * indexCount;
GLubyte *dst = nullptr;
......@@ -212,8 +212,6 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
size_t attribIndex,
const vk::Format &vertexFormat)
{
RendererVk *renderer = contextVk->getRenderer();
const angle::Format &srcFormat = vertexFormat.angleFormat();
const angle::Format &destFormat = vertexFormat.bufferFormat();
......@@ -231,7 +229,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
// Allocate buffer for results
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk);
ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
contextVk, numVertices * destFormatSize, nullptr, nullptr,
&mCurrentArrayBufferOffsets[attribIndex], nullptr));
......@@ -246,8 +244,8 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
params.srcOffset = binding.getOffset();
params.destOffset = static_cast<size_t>(mCurrentArrayBufferOffsets[attribIndex]);
ANGLE_TRY(renderer->getUtils().convertVertexBuffer(contextVk, mCurrentArrayBuffers[attribIndex],
&srcBuffer->getBuffer(), params));
ANGLE_TRY(contextVk->getUtils().convertVertexBuffer(
contextVk, mCurrentArrayBuffers[attribIndex], &srcBuffer->getBuffer(), params));
mCurrentArrayBufferHandles[attribIndex] =
mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
......@@ -269,7 +267,7 @@ angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
unsigned srcFormatSize = vertexFormat.angleFormat().pixelBytes;
unsigned dstFormatSize = vertexFormat.bufferFormat().pixelBytes;
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk);
size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
if (numVertices == 0)
......@@ -295,11 +293,11 @@ angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
return angle::Result::Continue;
}
ANGLE_INLINE void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
ANGLE_INLINE void VertexArrayVk::ensureConversionReleased(ContextVk *contextVk, size_t attribIndex)
{
if (mCurrentArrayBufferConversionCanRelease[attribIndex])
{
mCurrentArrayBufferConversion[attribIndex].release(renderer);
mCurrentArrayBufferConversion[attribIndex].release(contextVk);
mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
}
}
......@@ -474,7 +472,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
stride = binding.getStride();
}
ensureConversionReleased(renderer, attribIndex);
ensureConversionReleased(contextVk, attribIndex);
}
}
else
......@@ -483,7 +481,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = 0;
stride = vertexFormat.bufferFormat().pixelBytes;
ensureConversionReleased(renderer, attribIndex);
ensureConversionReleased(contextVk, attribIndex);
}
contextVk->onVertexAttributeChange(attribIndex, stride, binding.getDivisor(),
......@@ -499,7 +497,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBufferOffsets[attribIndex] = 0;
setDefaultPackedInput(contextVk, attribIndex);
ensureConversionReleased(renderer, attribIndex);
ensureConversionReleased(contextVk, attribIndex);
}
if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion.enabled)
......@@ -528,7 +526,7 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
indices, 0, &startVertex, &vertexCount));
RendererVk *renderer = contextVk->getRenderer();
mDynamicVertexData.releaseRetainedBuffers(renderer);
mDynamicVertexData.releaseRetainedBuffers(contextVk);
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
......@@ -661,7 +659,7 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
mTranslatedByteIndexData.releaseRetainedBuffers(contextVk);
ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
nullptr, nullptr,
......@@ -686,7 +684,7 @@ angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
// Note: this is a copy, which implicitly converts between formats. Once support for
// primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
// 0xFFFF.
ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
ANGLE_TRY(contextVk->getUtils().copyBuffer(contextVk, dest, src, params));
}
else
{
......
......@@ -99,7 +99,7 @@ class VertexArrayVk : public VertexArrayImpl
const gl::VertexBinding &binding,
size_t attribIndex,
const vk::Format &vertexFormat);
void ensureConversionReleased(RendererVk *renderer, size_t attribIndex);
void ensureConversionReleased(ContextVk *contextVk, size_t attribIndex);
angle::Result syncDirtyAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib,
......
......@@ -1540,12 +1540,12 @@ void GraphicsPipelineCache::destroy(VkDevice device)
mPayload.clear();
}
void GraphicsPipelineCache::release(RendererVk *renderer)
void GraphicsPipelineCache::release(ContextVk *context)
{
for (auto &item : mPayload)
{
vk::PipelineHelper &pipeline = item.second;
renderer->releaseObject(pipeline.getSerial(), &pipeline.getPipeline());
context->releaseObject(pipeline.getSerial(), &pipeline.getPipeline());
}
mPayload.clear();
......
......@@ -778,7 +778,7 @@ class GraphicsPipelineCache final : angle::NonCopyable
~GraphicsPipelineCache();
void destroy(VkDevice device);
void release(RendererVk *renderer);
void release(ContextVk *context);
void populate(const vk::GraphicsPipelineDesc &desc, vk::Pipeline &&pipeline);
......
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