Commit 896e7811 by Jamie Madill Committed by Commit Bot

Revert "Vulkan:Optimize SecondaryCommandBuffers"

This reverts commit 2219b18c. Reason for revert: Failing to compile on ASAN builders: https://ci.chromium.org/p/chromium/builders/try/linux-libfuzzer-asan-rel/134782 Currently blocking roll. Original change's description: > Vulkan:Optimize SecondaryCommandBuffers > > Optimize performance of SecondaryCommandBuffers and enable them as the > default build option. > To disable this set angle_enable_custom_vulkan_cmd_buffers=false in > your build args. > > This CL enhances the PoolAllocator to have a "fast" mode that can > be enabled at class creation. This mode uses an alignment of 1 byte and > enables a fastAllocation() call that avoids some bookkeeping overhead. > The SecondaryCommandBuffer uses this fastAllocation() function. > Furthermore the fast path of fast allocate, using the current page, > is inlined for maximum speed. > Jamie Madill also updated the SecondaryCommandBuffers to pre-allocate > blocks so that the commands occur linearly in memory. This speeds up > processing with improved cache coherency and minimizes overhead when > recording commands. > Also the core Draw functions and their state updates are all inlined > as well as the common functions to initialize commands and to copy > command pointer data. > > This change also includes some new, custom commands. One is > imageBarrier that is a specialized version of pipelineBarrier that only > performs a single image layout transition. > There are customized versions of various Draw commands to minimize > copying of parameters. > There are also specialized commands to bind[Graphics|Compute]Pipeline > that have the pipeline type built in to the command. > More custom commands and command data size optimizations will be made > in follow-on commits. > > Bug: angleproject:3136 > Change-Id: I35453cc2656bc8c51f0d84d1adef106900aca9a5 > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1497418 > Commit-Queue: Tobin Ehlis <tobine@google.com> > Reviewed-by: Jamie Madill <jmadill@chromium.org> TBR=tobine@google.com,syoussefi@chromium.org,jmadill@chromium.org Change-Id: I1c0bfe864ff343eb8ea6c88556523f8715c981d5 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: angleproject:3136 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1535998Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 9e586a0f
......@@ -86,7 +86,7 @@ declare_args() {
angle_vulkan_conformant_configs_only = is_official_build
# Enable custom (cpu-side) secondary command buffers
angle_enable_custom_vulkan_cmd_buffers = true
angle_enable_custom_vulkan_cmd_buffers = false
}
}
......
......@@ -15,7 +15,6 @@
#include "common/angleutils.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform.h"
#include "common/tls.h"
......@@ -37,48 +36,43 @@ PoolAllocator::PoolAllocator(int growthIncrement, int allocationAlignment)
#endif
mLocked(false)
{
if (mAlignment == 1)
{
// This is a special fast-path where fastAllocation() is enabled
mAlignmentMask = 0;
mHeaderSkip = sizeof(Header);
}
else
{
//
// Adjust mAlignment to be at least pointer aligned and
// power of 2.
//
size_t minAlign = sizeof(void *);
mAlignment &= ~(minAlign - 1);
if (mAlignment < minAlign)
mAlignment = minAlign;
mAlignment = gl::ceilPow2(mAlignment);
mAlignmentMask = mAlignment - 1;
//
// Adjust mAlignment to be at least pointer aligned and
// power of 2.
//
size_t minAlign = sizeof(void *);
mAlignment &= ~(minAlign - 1);
if (mAlignment < minAlign)
mAlignment = minAlign;
size_t a = 1;
while (a < mAlignment)
a <<= 1;
mAlignment = a;
mAlignmentMask = a - 1;
#if !defined(ANGLE_DISABLE_POOL_ALLOC)
//
// Align header skip
//
mHeaderSkip = minAlign;
if (mHeaderSkip < sizeof(Header))
{
mHeaderSkip = rx::roundUp(sizeof(Header), mAlignment);
}
}
//
// Don't allow page sizes we know are smaller than all common
// OS page sizes.
//
if (mPageSize < 4 * 1024)
mPageSize = 4 * 1024;
//
// A large mCurrentPageOffset indicates a new page needs to
// be obtained to allocate memory.
//
mCurrentPageOffset = mPageSize;
#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
//
// Align header skip
//
mHeaderSkip = minAlign;
if (mHeaderSkip < sizeof(Header))
{
mHeaderSkip = (sizeof(Header) + mAlignmentMask) & ~mAlignmentMask;
}
#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
mStack.push_back({});
#endif
}
......@@ -268,21 +262,7 @@ void *PoolAllocator::allocate(size_t numBytes)
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(memory) + mHeaderSkip);
return std::align(mAlignment, numBytes, unalignedPtr, allocationSize);
}
unsigned char *newPageAddr =
static_cast<unsigned char *>(allocateNewPage(numBytes, allocationSize));
return initializeAllocation(mInUseList, newPageAddr, numBytes);
#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
void *alloc = malloc(numBytes + mAlignmentMask);
mStack.back().push_back(alloc);
intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
intAlloc = rx::roundUp(intAlloc, mAlignment);
return reinterpret_cast<void *>(intAlloc);
#endif
}
void *PoolAllocator::allocateNewPage(size_t numBytes, size_t allocationSize)
{
//
// Need a simple page to allocate from.
//
......@@ -298,13 +278,22 @@ void *PoolAllocator::allocateNewPage(size_t numBytes, size_t allocationSize)
if (memory == 0)
return 0;
}
// Use placement-new to initialize header
new (memory) Header(mInUseList, 1);
mInUseList = memory;
unsigned char *ret = reinterpret_cast<unsigned char *>(mInUseList) + mHeaderSkip;
mCurrentPageOffset = (mHeaderSkip + allocationSize + mAlignmentMask) & ~mAlignmentMask;
return ret;
return initializeAllocation(mInUseList, ret, numBytes);
#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
void *alloc = malloc(numBytes + mAlignmentMask);
mStack.back().push_back(alloc);
intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
intAlloc = (intAlloc + mAlignmentMask) & ~mAlignmentMask;
return reinterpret_cast<void *>(intAlloc);
#endif
}
void PoolAllocator::lock()
......
......@@ -38,7 +38,6 @@
#include <vector>
#include "angleutils.h"
#include "common/debug.h"
namespace angle
{
......@@ -124,10 +123,6 @@ class PoolAllocator : angle::NonCopyable
{
public:
static const int kDefaultAlignment = 16;
//
// Create PoolAllocator. If alignment is be set to 1 byte then fastAllocate()
// function can be used to make allocations with less overhead.
//
PoolAllocator(int growthIncrement = 8 * 1024, int allocationAlignment = kDefaultAlignment);
//
......@@ -159,32 +154,6 @@ class PoolAllocator : angle::NonCopyable
void *allocate(size_t numBytes);
//
// Call fastAllocate() for a faster allocate function that does minimal bookkeeping
// preCondition: Allocator must have been created w/ alignment of 1
ANGLE_INLINE uint8_t *fastAllocate(size_t numBytes)
{
#if defined(ANGLE_DISABLE_POOL_ALLOC)
return allocate(numBytes);
#endif
ASSERT(mAlignment == 1);
// No multi-page allocations
ASSERT(numBytes <= (mPageSize - mHeaderSkip));
//
// Do the allocation, most likely case inline first, for efficiency.
//
if (numBytes <= mPageSize - mCurrentPageOffset)
{
//
// Safe to allocate from mCurrentPageOffset.
//
uint8_t *memory = reinterpret_cast<uint8_t *>(mInUseList) + mCurrentPageOffset;
mCurrentPageOffset += numBytes;
return memory;
}
return reinterpret_cast<uint8_t *>(allocateNewPage(numBytes, numBytes));
}
//
// There is no deallocate. The point of this class is that
// deallocation can be skipped by the user of it, as the model
// of use is to simultaneously deallocate everything at once
......@@ -236,8 +205,6 @@ class PoolAllocator : angle::NonCopyable
};
using AllocStack = std::vector<AllocState>;
// Slow path of allocation when we have to get a new page.
void *allocateNewPage(size_t numBytes, size_t allocationSize);
// Track allocations if and only if we're using guard blocks
void *initializeAllocation(Header *block, unsigned char *memory, size_t numBytes)
{
......
......@@ -139,9 +139,10 @@ void MakeDebugUtilsLabel(GLenum source, const char *marker, VkDebugUtilsLabelEXT
}
#if ANGLE_USE_CUSTOM_VULKAN_CMD_BUFFERS
constexpr VkSubpassContents kRenderPassContents = VK_SUBPASS_CONTENTS_INLINE;
static constexpr VkSubpassContents kRenderPassContents = VK_SUBPASS_CONTENTS_INLINE;
#else
constexpr VkSubpassContents kRenderPassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
static constexpr VkSubpassContents kRenderPassContents =
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
#endif
// Helpers to unify executeCommands call based on underlying cmd buffer type
......@@ -302,6 +303,7 @@ CommandGraphNode::CommandGraphNode(CommandGraphNodeFunction function,
CommandGraphNode::~CommandGraphNode()
{
mRenderPassFramebuffer.setHandle(VK_NULL_HANDLE);
// Command buffers are managed by the command pool, so don't need to be freed.
mOutsideRenderPassCommands.releaseHandle();
mInsideRenderPassCommands.releaseHandle();
......@@ -501,6 +503,7 @@ angle::Result CommandGraphNode::visitAndExecute(vk::Context *context,
RenderPass *renderPass = nullptr;
ANGLE_TRY(renderPassCache->getCompatibleRenderPass(context, serial, mRenderPassDesc,
&renderPass));
ANGLE_VK_TRY(context, mInsideRenderPassCommands.end());
VkRenderPassBeginInfo beginInfo = {};
......@@ -631,10 +634,7 @@ CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *po
: mEnableGraphDiagnostics(enableGraphDiagnostics),
mPoolAllocator(poolAllocator),
mLastBarrierIndex(kInvalidNodeIndex)
{
// Push so that allocations made from here will be recycled in clear() below.
mPoolAllocator->push();
}
{}
CommandGraph::~CommandGraph()
{
......@@ -776,12 +776,6 @@ bool CommandGraph::empty() const
void CommandGraph::clear()
{
mLastBarrierIndex = kInvalidNodeIndex;
// Release cmd graph pool memory now that cmds are submitted
// NOTE: This frees all memory since last push. Right now only the CommandGraph
// will push the allocator (at creation and below). If other people start
// pushing the allocator this (and/or the allocator) will need to be updated.
mPoolAllocator->pop();
mPoolAllocator->push();
// TODO(jmadill): Use pool allocator for performance. http://anglebug.com/2951
for (CommandGraphNode *node : mNodes)
......
......@@ -24,7 +24,6 @@ namespace rx
namespace vk
{
enum class VisitedState
{
Unvisited,
......@@ -120,11 +119,9 @@ class CommandGraphNode final : angle::NonCopyable
static void SetHappensBeforeDependencies(CommandGraphNode **beforeNodes,
size_t beforeNodesCount,
CommandGraphNode *afterNode);
static void SetHappensBeforeDependencies(CommandGraphNode *beforeNode,
CommandGraphNode **afterNodes,
size_t afterNodesCount);
bool hasParents() const;
bool hasChildren() const { return mHasChildren; }
......
......@@ -369,7 +369,9 @@ angle::Result ContextVk::handleDirtyPipeline(const gl::Context *context,
mGraphicsPipelineTransition.reset();
}
commandBuffer->bindGraphicsPipeline(mCurrentPipeline->getPipeline());
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline->getPipeline());
// Update the queue serial for the pipeline object.
ASSERT(mCurrentPipeline && mCurrentPipeline->valid());
mCurrentPipeline->updateSerial(mRenderer->getCurrentQueueSerial());
......@@ -447,8 +449,8 @@ angle::Result ContextVk::drawArrays(const gl::Context *context,
GLint first,
GLsizei count)
{
CommandBufferT *commandBuffer = nullptr;
uint32_t clampedVertexCount = gl::GetClampedVertexCount<uint32_t>(count);
CommandBufferT *commandBuffer = nullptr;
uint32_t clampedVertexCount = gl::GetClampedVertexCount<uint32_t>(count);
if (mode == gl::PrimitiveMode::LineLoop)
{
......@@ -460,7 +462,7 @@ angle::Result ContextVk::drawArrays(const gl::Context *context,
{
ANGLE_TRY(setupDraw(context, mode, first, count, 1, gl::DrawElementsType::InvalidEnum,
nullptr, mNonIndexedDirtyBitsMask, &commandBuffer));
commandBuffer->draw(clampedVertexCount, first);
commandBuffer->draw(clampedVertexCount, 1, first, 0);
}
return angle::Result::Continue;
......@@ -482,7 +484,7 @@ angle::Result ContextVk::drawArraysInstanced(const gl::Context *context,
CommandBufferT *commandBuffer = nullptr;
ANGLE_TRY(setupDraw(context, mode, first, count, instances, gl::DrawElementsType::InvalidEnum,
nullptr, mNonIndexedDirtyBitsMask, &commandBuffer));
commandBuffer->drawInstanced(gl::GetClampedVertexCount<uint32_t>(count), instances, first);
commandBuffer->draw(gl::GetClampedVertexCount<uint32_t>(count), instances, first, 0);
return angle::Result::Continue;
}
......@@ -501,7 +503,7 @@ angle::Result ContextVk::drawElements(const gl::Context *context,
else
{
ANGLE_TRY(setupIndexedDraw(context, mode, count, 1, type, indices, &commandBuffer));
commandBuffer->drawIndexed(count);
commandBuffer->drawIndexed(count, 1, 0, 0, 0);
}
return angle::Result::Continue;
......@@ -523,7 +525,7 @@ angle::Result ContextVk::drawElementsInstanced(const gl::Context *context,
CommandBufferT *commandBuffer = nullptr;
ANGLE_TRY(setupIndexedDraw(context, mode, count, instances, type, indices, &commandBuffer));
commandBuffer->drawIndexedInstanced(count, instances);
commandBuffer->drawIndexed(count, instances, 0, 0, 0);
return angle::Result::Continue;
}
......
......@@ -424,7 +424,7 @@ angle::Result FramebufferVk::blitWithCopy(ContextVk *contextVk,
VkImageAspectFlags aspectMask =
vk::GetDepthStencilAspectFlagsForCopy(blitDepthBuffer, blitStencilBuffer);
CommandBufferT *commandBuffer = nullptr;
CommandBufferT *commandBuffer;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(&mFramebuffer);
......@@ -509,7 +509,7 @@ angle::Result FramebufferVk::blitWithReadback(ContextVk *contextVk,
// Reinitialize the commandBuffer after a read pixels because it calls
// renderer->finish which makes command buffers obsolete.
CommandBufferT *commandBuffer = nullptr;
CommandBufferT *commandBuffer;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
// We read the bytes of the image in a buffer, now we have to copy them into the
......@@ -669,7 +669,7 @@ angle::Result FramebufferVk::blitWithCommand(ContextVk *contextVk,
vk::ImageHelper *dstImage = drawRenderTarget->getImageForWrite(&mFramebuffer);
CommandBufferT *commandBuffer = nullptr;
CommandBufferT *commandBuffer;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
const vk::Format &readImageFormat = readRenderTarget->getImageFormat();
......@@ -903,8 +903,8 @@ angle::Result FramebufferVk::clearWithClearAttachments(
// This command can only happen inside a render pass, so obtain one if its already happening
// or create a new one if not.
CommandBufferT *commandBuffer = nullptr;
vk::RecordingMode mode = vk::RecordingMode::Start;
CommandBufferT *commandBuffer = nullptr;
vk::RecordingMode mode = vk::RecordingMode::Start;
ANGLE_TRY(getCommandBufferForDraw(contextVk, &commandBuffer, &mode));
// The array layer is offset by the ImageView. So we shouldn't need to set a base array layer.
......
......@@ -506,7 +506,7 @@ RendererVk::RendererVk()
mCurrentQueueSerial(mQueueSerialFactory.generate()),
mDeviceLost(false),
mPipelineCacheVkUpdateTimeout(kPipelineCacheVkUpdatePeriod),
mPoolAllocator(kDefaultPoolAllocatorPageSize, 1),
mPoolAllocator(kDefaultPoolAllocatorPageSize),
mCommandGraph(kEnableCommandGraphDiagnostics, &mPoolAllocator),
mGpuEventsEnabled(false),
mGpuClockSync{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()},
......
......@@ -14,6 +14,102 @@ namespace rx
{
namespace vk
{
// Allocate/initialize memory for the command and return pointer to Cmd Header
template <class StructType>
StructType *SecondaryCommandBuffer::initCommand(CommandID cmdID, size_t variableSize)
{
size_t paramSize = sizeof(StructType);
size_t completeSize = sizeof(CommandHeader) + paramSize + variableSize;
CommandHeader *header = static_cast<CommandHeader *>(mAllocator->allocate(completeSize));
// Update cmd ID in header
header->id = cmdID;
header->next = nullptr;
// Update mHead ptr
mHead = (mHead == nullptr) ? header : mHead;
// Update prev cmd's "next" ptr and mLast ptr
if (mLast)
{
mLast->next = header;
}
// Update mLast ptr
mLast = header;
uint8_t *fixedParamPtr = reinterpret_cast<uint8_t *>(header) + sizeof(CommandHeader);
mPtrCmdData = fixedParamPtr + sizeof(StructType);
return reinterpret_cast<StructType *>(fixedParamPtr);
}
template <class PtrType>
void SecondaryCommandBuffer::storePointerParameter(const PtrType *paramData,
const PtrType **writePtr,
size_t sizeInBytes)
{
*writePtr = reinterpret_cast<const PtrType *>(mPtrCmdData);
memcpy(mPtrCmdData, paramData, sizeInBytes);
mPtrCmdData += sizeInBytes;
}
void SecondaryCommandBuffer::bindDescriptorSets(VkPipelineBindPoint bindPoint,
const PipelineLayout &layout,
uint32_t firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t *dynamicOffsets)
{
size_t descSize = descriptorSetCount * sizeof(VkDescriptorSet);
size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t);
size_t varSize = descSize + offsetSize;
BindDescriptorSetParams *paramStruct =
initCommand<BindDescriptorSetParams>(CommandID::BindDescriptorSets, varSize);
// Copy params into memory
paramStruct->bindPoint = bindPoint;
paramStruct->layout = layout.getHandle();
paramStruct->firstSet = firstSet;
paramStruct->descriptorSetCount = descriptorSetCount;
paramStruct->dynamicOffsetCount = dynamicOffsetCount;
// Copy variable sized data
storePointerParameter(descriptorSets, &paramStruct->descriptorSets, descSize);
storePointerParameter(dynamicOffsets, &paramStruct->dynamicOffsets, offsetSize);
}
void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
VkDeviceSize offset,
VkIndexType indexType)
{
BindIndexBufferParams *paramStruct =
initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer, 0);
paramStruct->buffer = buffer.getHandle();
paramStruct->offset = offset;
paramStruct->indexType = indexType;
}
void SecondaryCommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint,
const Pipeline &pipeline)
{
BindPipelineParams *paramStruct = initCommand<BindPipelineParams>(CommandID::BindPipeline, 0);
paramStruct->pipelineBindPoint = pipelineBindPoint;
paramStruct->pipeline = pipeline.getHandle();
}
void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *buffers,
const VkDeviceSize *offsets)
{
size_t buffSize = bindingCount * sizeof(VkBuffer);
size_t offsetSize = bindingCount * sizeof(VkDeviceSize);
BindVertexBuffersParams *paramStruct =
initCommand<BindVertexBuffersParams>(CommandID::BindVertexBuffers, buffSize + offsetSize);
// Copy params
paramStruct->firstBinding = firstBinding;
paramStruct->bindingCount = bindingCount;
// Copy variable sized data
storePointerParameter(buffers, &paramStruct->buffers, buffSize);
storePointerParameter(offsets, &paramStruct->offsets, offsetSize);
}
void SecondaryCommandBuffer::blitImage(const Image &srcImage,
VkImageLayout srcImageLayout,
const Image &dstImage,
......@@ -209,11 +305,37 @@ void SecondaryCommandBuffer::setScissor(uint32_t firstScissor,
storePointerParameter(scissors, &paramStruct->scissors, scissorSize);
}
void SecondaryCommandBuffer::draw(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance)
{
DrawParams *paramStruct = initCommand<DrawParams>(CommandID::Draw, 0);
paramStruct->vertexCount = vertexCount;
paramStruct->instanceCount = instanceCount;
paramStruct->firstVertex = firstVertex;
paramStruct->firstInstance = firstInstance;
}
void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance)
{
DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed, 0);
paramStruct->indexCount = indexCount;
paramStruct->instanceCount = instanceCount;
paramStruct->firstIndex = firstIndex;
paramStruct->vertexOffset = vertexOffset;
paramStruct->firstInstance = firstInstance;
}
void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
uint32_t groupCountY,
uint32_t groupCountZ)
{
DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch, 0);
paramStruct->groupCountX = groupCountX;
paramStruct->groupCountY = groupCountY;
paramStruct->groupCountZ = groupCountZ;
......@@ -233,10 +355,9 @@ void SecondaryCommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask,
size_t buffBarrierSize = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
size_t imgBarrierSize = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
CommandID::PipelineBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize);
CommandID::PipelinBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize);
paramStruct->srcStageMask = srcStageMask;
paramStruct->dstStageMask = dstStageMask;
paramStruct->dependencyFlags = dependencyFlags;
paramStruct->memoryBarrierCount = memoryBarrierCount;
paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
......@@ -247,26 +368,16 @@ void SecondaryCommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask,
storePointerParameter(imageMemoryBarriers, &paramStruct->imageMemoryBarriers, imgBarrierSize);
}
void SecondaryCommandBuffer::imageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkImageMemoryBarrier *imageMemoryBarrier)
{
ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(CommandID::ImageBarrier);
paramStruct->srcStageMask = srcStageMask;
paramStruct->dstStageMask = dstStageMask;
paramStruct->imageMemoryBarrier = *imageMemoryBarrier;
}
void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent, 0);
paramStruct->event = event;
paramStruct->stageMask = stageMask;
}
void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
{
ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent, 0);
paramStruct->event = event;
paramStruct->stageMask = stageMask;
}
......@@ -307,7 +418,7 @@ void SecondaryCommandBuffer::resetQueryPool(VkQueryPool queryPool,
uint32_t queryCount)
{
ResetQueryPoolParams *paramStruct =
initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool, 0);
paramStruct->queryPool = queryPool;
paramStruct->firstQuery = firstQuery;
paramStruct->queryCount = queryCount;
......@@ -317,7 +428,7 @@ void SecondaryCommandBuffer::beginQuery(VkQueryPool queryPool,
uint32_t query,
VkQueryControlFlags flags)
{
BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery);
BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery, 0);
paramStruct->queryPool = queryPool;
paramStruct->query = query;
paramStruct->flags = flags;
......@@ -325,7 +436,7 @@ void SecondaryCommandBuffer::beginQuery(VkQueryPool queryPool,
void SecondaryCommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
{
EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery, 0);
paramStruct->queryPool = queryPool;
paramStruct->query = query;
}
......@@ -335,276 +446,225 @@ void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStag
uint32_t query)
{
WriteTimestampParams *paramStruct =
initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
initCommand<WriteTimestampParams>(CommandID::WriteTimestamp, 0);
paramStruct->pipelineStage = pipelineStage;
paramStruct->queryPool = queryPool;
paramStruct->query = query;
}
ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command)
{
return reinterpret_cast<const CommandHeader *>(reinterpret_cast<const uint8_t *>(command) +
command->size);
}
// Parse the cmds in this cmd buffer into given primary cmd buffer
void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer)
{
for (const CommandHeader *command : mCommands)
for (CommandHeader *currentCommand = mHead; currentCommand;
currentCommand = currentCommand->next)
{
for (const CommandHeader *currentCommand = command;
currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
switch (currentCommand->id)
{
switch (currentCommand->id)
case CommandID::BindDescriptorSets:
{
BindDescriptorSetParams *params =
getParamPtr<BindDescriptorSetParams>(currentCommand);
vkCmdBindDescriptorSets(cmdBuffer, params->bindPoint, params->layout,
params->firstSet, params->descriptorSetCount,
params->descriptorSets, params->dynamicOffsetCount,
params->dynamicOffsets);
break;
}
case CommandID::BindIndexBuffer:
{
BindIndexBufferParams *params = getParamPtr<BindIndexBufferParams>(currentCommand);
vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset, params->indexType);
break;
}
case CommandID::BindPipeline:
{
BindPipelineParams *params = getParamPtr<BindPipelineParams>(currentCommand);
vkCmdBindPipeline(cmdBuffer, params->pipelineBindPoint, params->pipeline);
break;
}
case CommandID::BindVertexBuffers:
{
BindVertexBuffersParams *params =
getParamPtr<BindVertexBuffersParams>(currentCommand);
vkCmdBindVertexBuffers(cmdBuffer, params->firstBinding, params->bindingCount,
params->buffers, params->offsets);
break;
}
case CommandID::BlitImage:
{
BlitImageParams *params = getParamPtr<BlitImageParams>(currentCommand);
vkCmdBlitImage(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstImage, params->dstImageLayout, params->regionCount,
params->pRegions, params->filter);
break;
}
case CommandID::CopyBuffer:
{
CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand);
vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer,
params->regionCount, params->regions);
break;
}
case CommandID::CopyBufferToImage:
{
CopyBufferToImageParams *params =
getParamPtr<CopyBufferToImageParams>(currentCommand);
vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage,
params->dstImageLayout, params->regionCount,
params->regions);
break;
}
case CommandID::CopyImage:
{
CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand);
vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstImage, params->dstImageLayout, params->regionCount,
params->regions);
break;
}
case CommandID::CopyImageToBuffer:
{
CopyImageToBufferParams *params =
getParamPtr<CopyImageToBufferParams>(currentCommand);
vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstBuffer, params->regionCount, params->regions);
break;
}
case CommandID::ClearAttachments:
{
ClearAttachmentsParams *params =
getParamPtr<ClearAttachmentsParams>(currentCommand);
vkCmdClearAttachments(cmdBuffer, params->attachmentCount, params->attachments,
params->rectCount, params->rects);
break;
}
case CommandID::ClearColorImage:
{
ClearColorImageParams *params = getParamPtr<ClearColorImageParams>(currentCommand);
vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout, &params->color,
params->rangeCount, params->ranges);
break;
}
case CommandID::ClearDepthStencilImage:
{
ClearDepthStencilImageParams *params =
getParamPtr<ClearDepthStencilImageParams>(currentCommand);
vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout,
&params->depthStencil, params->rangeCount,
params->ranges);
break;
}
case CommandID::UpdateBuffer:
{
UpdateBufferParams *params = getParamPtr<UpdateBufferParams>(currentCommand);
vkCmdUpdateBuffer(cmdBuffer, params->buffer, params->dstOffset, params->dataSize,
params->data);
break;
}
case CommandID::PushConstants:
{
PushConstantsParams *params = getParamPtr<PushConstantsParams>(currentCommand);
vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
params->size, params->data);
break;
}
case CommandID::SetViewport:
{
SetViewportParams *params = getParamPtr<SetViewportParams>(currentCommand);
vkCmdSetViewport(cmdBuffer, params->firstViewport, params->viewportCount,
params->viewports);
break;
}
case CommandID::SetScissor:
{
SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand);
vkCmdSetScissor(cmdBuffer, params->firstScissor, params->scissorCount,
params->scissors);
break;
}
case CommandID::Draw:
{
DrawParams *params = getParamPtr<DrawParams>(currentCommand);
vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
params->firstVertex, params->firstInstance);
break;
}
case CommandID::DrawIndexed:
{
DrawIndexedParams *params = getParamPtr<DrawIndexedParams>(currentCommand);
vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount,
params->firstIndex, params->vertexOffset, params->firstInstance);
break;
}
case CommandID::Dispatch:
{
DispatchParams *params = getParamPtr<DispatchParams>(currentCommand);
vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY,
params->groupCountZ);
break;
}
case CommandID::PipelinBarrier:
{
PipelineBarrierParams *params = getParamPtr<PipelineBarrierParams>(currentCommand);
vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask,
params->dependencyFlags, params->memoryBarrierCount,
params->memoryBarriers, params->bufferMemoryBarrierCount,
params->bufferMemoryBarriers, params->imageMemoryBarrierCount,
params->imageMemoryBarriers);
break;
}
case CommandID::SetEvent:
{
SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
break;
}
case CommandID::ResetEvent:
{
ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
break;
}
case CommandID::WaitEvents:
{
WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
vkCmdWaitEvents(cmdBuffer, params->eventCount, params->events, params->srcStageMask,
params->dstStageMask, params->memoryBarrierCount,
params->memoryBarriers, params->bufferMemoryBarrierCount,
params->bufferMemoryBarriers, params->imageMemoryBarrierCount,
params->imageMemoryBarriers);
break;
}
case CommandID::ResetQueryPool:
{
ResetQueryPoolParams *params = getParamPtr<ResetQueryPoolParams>(currentCommand);
vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
params->queryCount);
break;
}
case CommandID::BeginQuery:
{
BeginQueryParams *params = getParamPtr<BeginQueryParams>(currentCommand);
vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, params->flags);
break;
}
case CommandID::EndQuery:
{
EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
vkCmdEndQuery(cmdBuffer, params->queryPool, params->query);
break;
}
case CommandID::WriteTimestamp:
{
WriteTimestampParams *params = getParamPtr<WriteTimestampParams>(currentCommand);
vkCmdWriteTimestamp(cmdBuffer, params->pipelineStage, params->queryPool,
params->query);
break;
}
default:
{
case CommandID::BeginQuery:
{
const BeginQueryParams *params = getParamPtr<BeginQueryParams>(currentCommand);
vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, params->flags);
break;
}
case CommandID::BindComputePipeline:
{
const BindPipelineParams *params =
getParamPtr<BindPipelineParams>(currentCommand);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, params->pipeline);
break;
}
case CommandID::BindDescriptorSets:
{
const BindDescriptorSetParams *params =
getParamPtr<BindDescriptorSetParams>(currentCommand);
vkCmdBindDescriptorSets(cmdBuffer, params->bindPoint, params->layout,
params->firstSet, params->descriptorSetCount,
params->descriptorSets, params->dynamicOffsetCount,
params->dynamicOffsets);
break;
}
case CommandID::BindGraphicsPipeline:
{
const BindPipelineParams *params =
getParamPtr<BindPipelineParams>(currentCommand);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, params->pipeline);
break;
}
case CommandID::BindIndexBuffer:
{
const BindIndexBufferParams *params =
getParamPtr<BindIndexBufferParams>(currentCommand);
vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset,
params->indexType);
break;
}
case CommandID::BindVertexBuffers:
{
const BindVertexBuffersParams *params =
getParamPtr<BindVertexBuffersParams>(currentCommand);
const VkBuffer *buffers =
Offset<VkBuffer>(params, sizeof(BindVertexBuffersParams));
const VkDeviceSize *offsets =
Offset<VkDeviceSize>(buffers, sizeof(VkBuffer) * params->bindingCount);
vkCmdBindVertexBuffers(cmdBuffer, 0, params->bindingCount, buffers, offsets);
break;
}
case CommandID::BlitImage:
{
const BlitImageParams *params = getParamPtr<BlitImageParams>(currentCommand);
vkCmdBlitImage(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstImage, params->dstImageLayout, params->regionCount,
params->pRegions, params->filter);
break;
}
case CommandID::ClearAttachments:
{
const ClearAttachmentsParams *params =
getParamPtr<ClearAttachmentsParams>(currentCommand);
vkCmdClearAttachments(cmdBuffer, params->attachmentCount, params->attachments,
params->rectCount, params->rects);
break;
}
case CommandID::ClearColorImage:
{
const ClearColorImageParams *params =
getParamPtr<ClearColorImageParams>(currentCommand);
vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout,
&params->color, params->rangeCount, params->ranges);
break;
}
case CommandID::ClearDepthStencilImage:
{
const ClearDepthStencilImageParams *params =
getParamPtr<ClearDepthStencilImageParams>(currentCommand);
vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout,
&params->depthStencil, params->rangeCount,
params->ranges);
break;
}
case CommandID::CopyBuffer:
{
const CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand);
vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer,
params->regionCount, params->regions);
break;
}
case CommandID::CopyBufferToImage:
{
const CopyBufferToImageParams *params =
getParamPtr<CopyBufferToImageParams>(currentCommand);
vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage,
params->dstImageLayout, params->regionCount,
params->regions);
break;
}
case CommandID::CopyImage:
{
const CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand);
vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstImage, params->dstImageLayout, params->regionCount,
params->regions);
break;
}
case CommandID::CopyImageToBuffer:
{
const CopyImageToBufferParams *params =
getParamPtr<CopyImageToBufferParams>(currentCommand);
vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout,
params->dstBuffer, params->regionCount, params->regions);
break;
}
case CommandID::Dispatch:
{
const DispatchParams *params = getParamPtr<DispatchParams>(currentCommand);
vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY,
params->groupCountZ);
break;
}
case CommandID::Draw:
{
const DrawParams *params = getParamPtr<DrawParams>(currentCommand);
vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0);
break;
}
case CommandID::DrawIndexed:
{
const DrawIndexedParams *params =
getParamPtr<DrawIndexedParams>(currentCommand);
vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0);
break;
}
case CommandID::DrawIndexedInstanced:
{
const DrawIndexedInstancedParams *params =
getParamPtr<DrawIndexedInstancedParams>(currentCommand);
vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0);
break;
}
case CommandID::DrawInstanced:
{
const DrawInstancedParams *params =
getParamPtr<DrawInstancedParams>(currentCommand);
vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
params->firstVertex, 0);
break;
}
case CommandID::EndQuery:
{
const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
vkCmdEndQuery(cmdBuffer, params->queryPool, params->query);
break;
}
case CommandID::ImageBarrier:
{
const ImageBarrierParams *params =
getParamPtr<ImageBarrierParams>(currentCommand);
vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
0, nullptr, 0, nullptr, 1, &params->imageMemoryBarrier);
break;
}
case CommandID::PipelineBarrier:
{
const PipelineBarrierParams *params =
getParamPtr<PipelineBarrierParams>(currentCommand);
vkCmdPipelineBarrier(
cmdBuffer, params->srcStageMask, params->dstStageMask,
params->dependencyFlags, params->memoryBarrierCount, params->memoryBarriers,
params->bufferMemoryBarrierCount, params->bufferMemoryBarriers,
params->imageMemoryBarrierCount, params->imageMemoryBarriers);
break;
}
case CommandID::PushConstants:
{
const PushConstantsParams *params =
getParamPtr<PushConstantsParams>(currentCommand);
vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
params->size, params->data);
break;
}
case CommandID::ResetEvent:
{
const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
break;
}
case CommandID::ResetQueryPool:
{
const ResetQueryPoolParams *params =
getParamPtr<ResetQueryPoolParams>(currentCommand);
vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
params->queryCount);
break;
}
case CommandID::SetEvent:
{
const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
break;
}
case CommandID::SetScissor:
{
const SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand);
vkCmdSetScissor(cmdBuffer, params->firstScissor, params->scissorCount,
params->scissors);
break;
}
case CommandID::SetViewport:
{
const SetViewportParams *params =
getParamPtr<SetViewportParams>(currentCommand);
vkCmdSetViewport(cmdBuffer, params->firstViewport, params->viewportCount,
params->viewports);
break;
}
case CommandID::UpdateBuffer:
{
const UpdateBufferParams *params =
getParamPtr<UpdateBufferParams>(currentCommand);
vkCmdUpdateBuffer(cmdBuffer, params->buffer, params->dstOffset,
params->dataSize, params->data);
break;
}
case CommandID::WaitEvents:
{
const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
vkCmdWaitEvents(cmdBuffer, params->eventCount, params->events,
params->srcStageMask, params->dstStageMask,
params->memoryBarrierCount, params->memoryBarriers,
params->bufferMemoryBarrierCount, params->bufferMemoryBarriers,
params->imageMemoryBarrierCount, params->imageMemoryBarriers);
break;
}
case CommandID::WriteTimestamp:
{
const WriteTimestampParams *params =
getParamPtr<WriteTimestampParams>(currentCommand);
vkCmdWriteTimestamp(cmdBuffer, params->pipelineStage, params->queryPool,
params->query);
break;
}
default:
{
UNREACHABLE();
break;
}
UNREACHABLE();
break;
}
}
}
......
......@@ -22,46 +22,40 @@ namespace rx
namespace vk
{
enum class CommandID : uint16_t
{
// Invalid cmd used to mark end of sequence of commands
Invalid = 0,
BeginQuery,
BindComputePipeline,
BindDescriptorSets,
BindGraphicsPipeline,
BindIndexBuffer,
BindVertexBuffers,
BlitImage,
ClearAttachments,
ClearColorImage,
ClearDepthStencilImage,
CopyBuffer,
CopyBufferToImage,
CopyImage,
CopyImageToBuffer,
Dispatch,
Draw,
DrawIndexed,
DrawIndexedInstanced,
DrawInstanced,
EndQuery,
ImageBarrier,
PipelineBarrier,
PushConstants,
ResetEvent,
ResetQueryPool,
SetEvent,
SetScissor,
SetViewport,
UpdateBuffer,
WaitEvents,
WriteTimestamp,
enum class CommandID
{
// State update cmds
BindDescriptorSets = 0,
BindIndexBuffer = 1,
BindPipeline = 2,
BindVertexBuffers = 3,
BlitImage = 4,
CopyBuffer = 5,
CopyBufferToImage = 6,
CopyImage = 7,
CopyImageToBuffer = 8,
ClearAttachments = 9,
ClearColorImage = 10,
ClearDepthStencilImage = 11,
UpdateBuffer = 12,
PushConstants = 13,
SetViewport = 14,
SetScissor = 15,
// Draw/dispatch cmds
Draw = 16,
DrawIndexed = 17,
Dispatch = 18,
// Sync & Query cmds
PipelinBarrier = 19,
ResetEvent = 20,
SetEvent = 21,
WaitEvents = 22,
ResetQueryPool = 23,
BeginQuery = 24,
EndQuery = 25,
WriteTimestamp = 26,
};
#define VERIFY_4_BYTE_ALIGNMENT(StructName) \
static_assert((sizeof(StructName) % 4) == 0, "Check StructName alignment");
// Structs to encapsulate parameters for different commands
// This makes it easy to know the size of params & to copy params
// TODO: Could optimize the size of some of these structs through bit-packing
......@@ -76,7 +70,6 @@ struct BindDescriptorSetParams
uint32_t dynamicOffsetCount;
const uint32_t *dynamicOffsets;
};
VERIFY_4_BYTE_ALIGNMENT(BindDescriptorSetParams)
struct BindIndexBufferParams
{
......@@ -84,20 +77,20 @@ struct BindIndexBufferParams
VkDeviceSize offset;
VkIndexType indexType;
};
VERIFY_4_BYTE_ALIGNMENT(BindIndexBufferParams)
struct BindPipelineParams
{
VkPipelineBindPoint pipelineBindPoint;
VkPipeline pipeline;
};
VERIFY_4_BYTE_ALIGNMENT(BindPipelineParams)
struct BindVertexBuffersParams
{
// ANGLE always has firstBinding of 0 so not storing that currently
uint32_t firstBinding;
uint32_t bindingCount;
const VkBuffer *buffers;
const VkDeviceSize *offsets;
};
VERIFY_4_BYTE_ALIGNMENT(BindVertexBuffersParams)
struct BlitImageParams
{
......@@ -109,7 +102,6 @@ struct BlitImageParams
const VkImageBlit *pRegions;
VkFilter filter;
};
VERIFY_4_BYTE_ALIGNMENT(BlitImageParams)
struct CopyBufferParams
{
......@@ -118,7 +110,6 @@ struct CopyBufferParams
uint32_t regionCount;
const VkBufferCopy *regions;
};
VERIFY_4_BYTE_ALIGNMENT(CopyBufferParams)
struct CopyBufferToImageParams
{
......@@ -128,7 +119,6 @@ struct CopyBufferToImageParams
uint32_t regionCount;
const VkBufferImageCopy *regions;
};
VERIFY_4_BYTE_ALIGNMENT(CopyBufferToImageParams)
struct CopyImageParams
{
......@@ -139,7 +129,6 @@ struct CopyImageParams
uint32_t regionCount;
const VkImageCopy *regions;
};
VERIFY_4_BYTE_ALIGNMENT(CopyImageParams)
struct CopyImageToBufferParams
{
......@@ -149,7 +138,6 @@ struct CopyImageToBufferParams
uint32_t regionCount;
const VkBufferImageCopy *regions;
};
VERIFY_4_BYTE_ALIGNMENT(CopyImageToBufferParams)
struct ClearAttachmentsParams
{
......@@ -158,7 +146,6 @@ struct ClearAttachmentsParams
uint32_t rectCount;
const VkClearRect *rects;
};
VERIFY_4_BYTE_ALIGNMENT(ClearAttachmentsParams)
struct ClearColorImageParams
{
......@@ -168,7 +155,6 @@ struct ClearColorImageParams
uint32_t rangeCount;
const VkImageSubresourceRange *ranges;
};
VERIFY_4_BYTE_ALIGNMENT(ClearColorImageParams)
struct ClearDepthStencilImageParams
{
......@@ -178,7 +164,6 @@ struct ClearDepthStencilImageParams
uint32_t rangeCount;
const VkImageSubresourceRange *ranges;
};
VERIFY_4_BYTE_ALIGNMENT(ClearDepthStencilImageParams)
struct UpdateBufferParams
{
......@@ -187,7 +172,6 @@ struct UpdateBufferParams
VkDeviceSize dataSize;
const void *data;
};
VERIFY_4_BYTE_ALIGNMENT(UpdateBufferParams)
struct PushConstantsParams
{
......@@ -197,7 +181,6 @@ struct PushConstantsParams
uint32_t size;
const void *data;
};
VERIFY_4_BYTE_ALIGNMENT(PushConstantsParams)
struct SetViewportParams
{
......@@ -205,7 +188,6 @@ struct SetViewportParams
uint32_t viewportCount;
const VkViewport *viewports;
};
VERIFY_4_BYTE_ALIGNMENT(SetViewportParams)
struct SetScissorParams
{
......@@ -213,35 +195,23 @@ struct SetScissorParams
uint32_t scissorCount;
const VkRect2D *scissors;
};
VERIFY_4_BYTE_ALIGNMENT(SetScissorParams)
struct DrawParams
{
uint32_t vertexCount;
uint32_t firstVertex;
};
VERIFY_4_BYTE_ALIGNMENT(DrawParams)
struct DrawInstancedParams
{
uint32_t vertexCount;
uint32_t instanceCount;
uint32_t firstVertex;
uint32_t firstInstance;
};
VERIFY_4_BYTE_ALIGNMENT(DrawInstancedParams)
struct DrawIndexedParams
{
uint32_t indexCount;
};
VERIFY_4_BYTE_ALIGNMENT(DrawIndexedParams)
struct DrawIndexedInstancedParams
{
uint32_t indexCount;
uint32_t instanceCount;
uint32_t firstIndex;
int32_t vertexOffset;
uint32_t firstInstance;
};
VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedParams)
struct DispatchParams
{
......@@ -249,7 +219,6 @@ struct DispatchParams
uint32_t groupCountY;
uint32_t groupCountZ;
};
VERIFY_4_BYTE_ALIGNMENT(DispatchParams)
struct PipelineBarrierParams
{
......@@ -263,29 +232,18 @@ struct PipelineBarrierParams
uint32_t imageMemoryBarrierCount;
const VkImageMemoryBarrier *imageMemoryBarriers;
};
VERIFY_4_BYTE_ALIGNMENT(PipelineBarrierParams)
struct ImageBarrierParams
{
VkPipelineStageFlags srcStageMask;
VkPipelineStageFlags dstStageMask;
VkImageMemoryBarrier imageMemoryBarrier;
};
VERIFY_4_BYTE_ALIGNMENT(ImageBarrierParams)
struct SetEventParams
{
VkEvent event;
VkPipelineStageFlags stageMask;
};
VERIFY_4_BYTE_ALIGNMENT(SetEventParams)
struct ResetEventParams
{
VkEvent event;
VkPipelineStageFlags stageMask;
};
VERIFY_4_BYTE_ALIGNMENT(ResetEventParams)
struct WaitEventsParams
{
......@@ -300,7 +258,6 @@ struct WaitEventsParams
uint32_t imageMemoryBarrierCount;
const VkImageMemoryBarrier *imageMemoryBarriers;
};
VERIFY_4_BYTE_ALIGNMENT(WaitEventsParams)
struct ResetQueryPoolParams
{
......@@ -308,7 +265,6 @@ struct ResetQueryPoolParams
uint32_t firstQuery;
uint32_t queryCount;
};
VERIFY_4_BYTE_ALIGNMENT(ResetQueryPoolParams)
struct BeginQueryParams
{
......@@ -316,14 +272,12 @@ struct BeginQueryParams
uint32_t query;
VkQueryControlFlags flags;
};
VERIFY_4_BYTE_ALIGNMENT(BeginQueryParams)
struct EndQueryParams
{
VkQueryPool queryPool;
uint32_t query;
};
VERIFY_4_BYTE_ALIGNMENT(EndQueryParams)
struct WriteTimestampParams
{
......@@ -331,34 +285,19 @@ struct WriteTimestampParams
VkQueryPool queryPool;
uint32_t query;
};
VERIFY_4_BYTE_ALIGNMENT(WriteTimestampParams)
// Header for every cmd in custom cmd buffer
struct CommandHeader
{
CommandID id;
uint16_t size;
CommandHeader *next;
};
static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size");
template <typename DestT, typename T>
ANGLE_INLINE DestT *Offset(T *ptr, size_t bytes)
{
return reinterpret_cast<DestT *>((reinterpret_cast<uint8_t *>(ptr) + bytes));
}
template <typename DestT, typename T>
ANGLE_INLINE const DestT *Offset(const T *ptr, size_t bytes)
{
return reinterpret_cast<const DestT *>((reinterpret_cast<const uint8_t *>(ptr) + bytes));
}
class SecondaryCommandBuffer final : angle::NonCopyable
{
public:
SecondaryCommandBuffer();
~SecondaryCommandBuffer();
SecondaryCommandBuffer() : mHead(nullptr), mLast(nullptr), mAllocator(nullptr) {}
~SecondaryCommandBuffer() {}
// Add commands
void bindDescriptorSets(VkPipelineBindPoint bindPoint,
......@@ -371,9 +310,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable
void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
void bindGraphicsPipeline(const Pipeline &pipeline);
void bindComputePipeline(const Pipeline &pipeline);
void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const Pipeline &pipeline);
void bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
......@@ -443,13 +380,16 @@ class SecondaryCommandBuffer final : angle::NonCopyable
void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *viewports);
void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *scissors);
void draw(uint32_t vertexCount, uint32_t firstVertex);
void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
void draw(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance);
void drawIndexed(uint32_t indexCount);
void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
void drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance);
void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
......@@ -463,10 +403,6 @@ class SecondaryCommandBuffer final : angle::NonCopyable
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier *imageMemoryBarriers);
void imageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkImageMemoryBarrier *imageMemoryBarrier);
void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
void waitEvents(uint32_t eventCount,
......@@ -491,87 +427,25 @@ class SecondaryCommandBuffer final : angle::NonCopyable
// Parse the cmds in this cmd buffer into given primary cmd buffer for execution
void executeCommands(VkCommandBuffer cmdBuffer);
// Pool Alloc uses 16kB pages w/ 16byte header = 16368bytes. To minimize waste
// using a 16368/12 = 1364. Also better perf than 1024 due to fewer block allocations
static constexpr size_t kBlockSize = 1364;
// Make sure block size is 4-byte aligned to avoid Android errors
static_assert((kBlockSize % 4) == 0, "Check kBlockSize alignment");
// Initialize the SecondaryCommandBuffer by setting the allocator it will use
void initialize(angle::PoolAllocator *allocator)
{
ASSERT(allocator);
mAllocator = allocator;
allocateNewBlock();
// Set first command to Invalid to start
reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
}
void initialize(angle::PoolAllocator *allocator) { mAllocator = allocator; }
// This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator
void releaseHandle() { mAllocator = nullptr; }
// The SecondaryCommandBuffer is valid if it's been initialized
bool valid() { return mAllocator != nullptr; }
private:
template <class StructType>
ANGLE_INLINE StructType *commonInit(CommandID cmdID, size_t allocationSize)
{
mCurrentBytesRemaining -= allocationSize;
CommandHeader *header = reinterpret_cast<CommandHeader *>(mCurrentWritePointer);
header->id = cmdID;
header->size = static_cast<uint16_t>(allocationSize);
ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max());
mCurrentWritePointer += allocationSize;
// Set next cmd header to Invalid (0) so cmd sequence will be terminated
reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
return Offset<StructType>(header, sizeof(CommandHeader));
}
ANGLE_INLINE void allocateNewBlock()
{
ASSERT(mAllocator);
mCurrentWritePointer = mAllocator->fastAllocate(kBlockSize);
mCurrentBytesRemaining = kBlockSize;
mCommands.push_back(reinterpret_cast<CommandHeader *>(mCurrentWritePointer));
}
// Allocate and initialize memory for given commandID & variable param size
// returning a pointer to the start of the commands parameter data and updating
// mPtrCmdData to just past the fixed parameter data.
template <class StructType>
ANGLE_INLINE StructType *initCommand(CommandID cmdID, size_t variableSize)
{
constexpr size_t fixedAllocationSize = sizeof(StructType) + sizeof(CommandHeader);
const size_t allocationSize = fixedAllocationSize + variableSize;
// Make sure we have enough room to mark follow-on header "Invalid"
if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader)))
{
allocateNewBlock();
}
mPtrCmdData = mCurrentWritePointer + fixedAllocationSize;
return commonInit<StructType>(cmdID, allocationSize);
}
// Initialize a command that doesn't have variable-sized ptr data
template <class StructType>
ANGLE_INLINE StructType *initCommand(CommandID cmdID)
{
constexpr size_t allocationSize = sizeof(StructType) + sizeof(CommandHeader);
// Make sure we have enough room to mark follow-on header "Invalid"
if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader)))
{
allocateNewBlock();
}
return commonInit<StructType>(cmdID, allocationSize);
}
StructType *initCommand(CommandID cmdID, size_t variableSize);
// Return a ptr to the parameter type
template <class StructType>
const StructType *getParamPtr(const CommandHeader *header) const
StructType *getParamPtr(CommandHeader *header)
{
return reinterpret_cast<const StructType *>(reinterpret_cast<const uint8_t *>(header) +
sizeof(CommandHeader));
return reinterpret_cast<StructType *>(reinterpret_cast<char *>(header) +
sizeof(CommandHeader));
}
// Copy sizeInBytes data from paramData to mPtrCmdData and assign *writePtr
// to mPtrCmdData. Then increment mPtrCmdData by sizeInBytes.
......@@ -579,132 +453,18 @@ class SecondaryCommandBuffer final : angle::NonCopyable
template <class PtrType>
void storePointerParameter(const PtrType *paramData,
const PtrType **writePtr,
size_t sizeInBytes)
{
if (sizeInBytes == 0)
return;
*writePtr = reinterpret_cast<const PtrType *>(mPtrCmdData);
memcpy(mPtrCmdData, paramData, sizeInBytes);
mPtrCmdData += sizeInBytes;
}
std::vector<CommandHeader *> mCommands;
size_t sizeInBytes);
// Allocator used by this class. If non-null then the class is valid.
// Pointer to start of cmd buffer
CommandHeader *mHead;
// Last command inserted in cmd buffer
CommandHeader *mLast;
angle::PoolAllocator *mAllocator;
uint8_t *mCurrentWritePointer;
size_t mCurrentBytesRemaining;
// Ptr to write variable ptr data section of cmd into.
// This is set to just past fixed parameter data when initCommand() is called
uint8_t *mPtrCmdData;
};
ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer()
: mAllocator(nullptr), mCurrentWritePointer(nullptr), mCurrentBytesRemaining(0)
{}
ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer() {}
ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(VkPipelineBindPoint bindPoint,
const PipelineLayout &layout,
uint32_t firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *descriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t *dynamicOffsets)
{
size_t descSize = descriptorSetCount * sizeof(VkDescriptorSet);
size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t);
size_t varSize = descSize + offsetSize;
BindDescriptorSetParams *paramStruct =
initCommand<BindDescriptorSetParams>(CommandID::BindDescriptorSets, varSize);
// Copy params into memory
paramStruct->bindPoint = bindPoint;
paramStruct->layout = layout.getHandle();
paramStruct->firstSet = firstSet;
paramStruct->descriptorSetCount = descriptorSetCount;
paramStruct->dynamicOffsetCount = dynamicOffsetCount;
// Copy variable sized data
storePointerParameter(descriptorSets, &paramStruct->descriptorSets, descSize);
storePointerParameter(dynamicOffsets, &paramStruct->dynamicOffsets, offsetSize);
}
ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
VkDeviceSize offset,
VkIndexType indexType)
{
BindIndexBufferParams *paramStruct =
initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
paramStruct->buffer = buffer.getHandle();
paramStruct->offset = offset;
paramStruct->indexType = indexType;
}
ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
{
BindPipelineParams *paramStruct =
initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
paramStruct->pipeline = pipeline.getHandle();
}
ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
{
BindPipelineParams *paramStruct =
initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
paramStruct->pipeline = pipeline.getHandle();
}
ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *buffers,
const VkDeviceSize *offsets)
{
ASSERT(firstBinding == 0);
size_t buffersSize = bindingCount * sizeof(VkBuffer);
size_t offsetsSize = bindingCount * sizeof(VkDeviceSize);
BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
CommandID::BindVertexBuffers, buffersSize + offsetsSize);
// Copy params
paramStruct->bindingCount = bindingCount;
uint8_t *writePointer = Offset<uint8_t>(paramStruct, sizeof(BindVertexBuffersParams));
memcpy(writePointer, buffers, buffersSize);
writePointer += buffersSize;
memcpy(writePointer, offsets, offsetsSize);
}
ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
{
DrawParams *paramStruct = initCommand<DrawParams>(CommandID::Draw);
paramStruct->vertexCount = vertexCount;
paramStruct->firstVertex = firstVertex;
}
ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex)
{
DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
paramStruct->vertexCount = vertexCount;
paramStruct->instanceCount = instanceCount;
paramStruct->firstVertex = firstVertex;
}
ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
{
DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
paramStruct->indexCount = indexCount;
}
ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
uint32_t instanceCount)
{
DrawIndexedInstancedParams *paramStruct =
initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
paramStruct->indexCount = indexCount;
paramStruct->instanceCount = instanceCount;
}
} // namespace vk
} // namespace rx
......
......@@ -503,18 +503,18 @@ angle::Result WindowSurfaceVk::recreateSwapchain(DisplayVk *displayVk,
swapchainInfo.imageFormat = nativeFormat;
swapchainInfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
// Note: Vulkan doesn't allow 0-width/height swapchains.
swapchainInfo.imageExtent.width = std::max(extents.width, 1);
swapchainInfo.imageExtent.height = std::max(extents.height, 1);
swapchainInfo.imageArrayLayers = 1;
swapchainInfo.imageUsage = kImageUsageFlags;
swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapchainInfo.queueFamilyIndexCount = 0;
swapchainInfo.pQueueFamilyIndices = nullptr;
swapchainInfo.preTransform = mPreTransform;
swapchainInfo.compositeAlpha = mCompositeAlpha;
swapchainInfo.presentMode = mDesiredSwapchainPresentMode;
swapchainInfo.clipped = VK_TRUE;
swapchainInfo.oldSwapchain = oldSwapchain;
swapchainInfo.imageExtent.width = std::max(extents.width, 1);
swapchainInfo.imageExtent.height = std::max(extents.height, 1);
swapchainInfo.imageArrayLayers = 1;
swapchainInfo.imageUsage = kImageUsageFlags;
swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapchainInfo.queueFamilyIndexCount = 0;
swapchainInfo.pQueueFamilyIndices = nullptr;
swapchainInfo.preTransform = mPreTransform;
swapchainInfo.compositeAlpha = mCompositeAlpha;
swapchainInfo.presentMode = mDesiredSwapchainPresentMode;
swapchainInfo.clipped = VK_TRUE;
swapchainInfo.oldSwapchain = oldSwapchain;
// TODO(syoussefi): Once EGL_SWAP_BEHAVIOR_PRESERVED_BIT is supported, the contents of the old
// swapchain need to carry over to the new one. http://anglebug.com/2942
......@@ -738,7 +738,7 @@ angle::Result WindowSurfaceVk::present(DisplayVk *displayVk,
std::vector<VkRectLayerKHR> vk_rects;
if (renderer->getFeatures().supportsIncrementalPresent && (n_rects > 0))
{
EGLint *egl_rects = rects;
EGLint *egl_rects = rects;
presentRegion.rectangleCount = n_rects;
vk_rects.resize(n_rects);
for (EGLint rect = 0; rect < n_rects; rect++)
......
......@@ -1004,7 +1004,7 @@ angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
sourceRowPitch, imageData + bufferOffset));
}
CommandBufferT *commandBuffer = nullptr;
CommandBufferT *commandBuffer;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
return mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0), getLevelCount(),
commandBuffer);
......
......@@ -335,7 +335,7 @@ angle::Result UtilsVk::setupProgram(vk::Context *context,
program->setShader(gl::ShaderType::Compute, fsCsShader);
ANGLE_TRY(program->getComputePipeline(context, pipelineLayout.get(), &pipelineAndSerial));
pipelineAndSerial->updateSerial(serial);
commandBuffer->bindComputePipeline(pipelineAndSerial->get());
commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
}
else
{
......@@ -350,7 +350,7 @@ angle::Result UtilsVk::setupProgram(vk::Context *context,
context, &renderer->getRenderPassCache(), renderer->getPipelineCache(), serial,
pipelineLayout.get(), *pipelineDesc, gl::AttributesMask(), &descPtr, &helper));
helper->updateSerial(serial);
commandBuffer->bindGraphicsPipeline(helper->getPipeline());
commandBuffer->bindPipeline(bindPoint, helper->getPipeline());
}
if (descriptorSet != VK_NULL_HANDLE)
......@@ -657,7 +657,9 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
ANGLE_TRY(setupProgram(contextVk, Function::ImageClear, fragmentShader, vertexShader,
&mImageClearProgram, &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
sizeof(shaderParams), commandBuffer));
commandBuffer->draw(6, 0);
commandBuffer->draw(6, 1, 0, 0);
return angle::Result::Continue;
}
......@@ -781,7 +783,9 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
ANGLE_TRY(setupProgram(contextVk, Function::ImageCopy, fragmentShader, vertexShader,
&mImageCopyPrograms[flags], &pipelineDesc, descriptorSet, &shaderParams,
sizeof(shaderParams), commandBuffer));
commandBuffer->draw(6, 0);
commandBuffer->draw(6, 1, 0, 0);
descriptorPoolBinding.reset();
return angle::Result::Continue;
......
......@@ -1064,7 +1064,7 @@ void LineLoopHelper::Draw(uint32_t count, CommandBufferT *commandBuffer)
{
// Our first index is always 0 because that's how we set it up in createIndexBuffer*.
// Note: this could theoretically overflow and wrap to zero.
commandBuffer->drawIndexed(count + 1);
commandBuffer->drawIndexed(count + 1, 1, 0, 0, 0);
}
// BufferHelper implementation.
......@@ -1603,9 +1603,10 @@ void ImageHelper::forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask,
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = mLayerCount;
commandBuffer->imageBarrier(transitionFrom.srcStageMask, transitionTo.dstStageMask,
&imageMemoryBarrier);
mCurrentLayout = newLayout;
commandBuffer->pipelineBarrier(transitionFrom.srcStageMask, transitionTo.dstStageMask, 0, 0,
nullptr, 0, nullptr, 1, &imageMemoryBarrier);
mCurrentLayout = newLayout;
mCurrentQueueFamilyIndex = newQueueFamilyIndex;
}
......@@ -1613,6 +1614,7 @@ void ImageHelper::clearColor(const VkClearColorValue &color,
uint32_t baseMipLevel,
uint32_t levelCount,
CommandBufferT *commandBuffer)
{
clearColorLayer(color, baseMipLevel, levelCount, 0, mLayerCount, commandBuffer);
}
......@@ -1736,8 +1738,10 @@ angle::Result ImageHelper::generateMipmapsWithBlit(ContextVk *contextVk, GLuint
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
// We can do it for all layers at once.
commandBuffer->imageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
&barrier);
commandBuffer->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
&barrier);
VkImageBlit blit = {};
blit.srcOffsets[0] = {0, 0, 0};
blit.srcOffsets[1] = {mipWidth, mipHeight, 1};
......@@ -1766,8 +1770,9 @@ angle::Result ImageHelper::generateMipmapsWithBlit(ContextVk *contextVk, GLuint
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
// We can do it for all layers at once.
commandBuffer->imageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
&barrier);
commandBuffer->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
// This is just changing the internal state of the image helper so that the next call
// to changeLayout will use this layout as the "oldLayout" argument.
mCurrentLayout = ImageLayout::TransferSrc;
......
......@@ -626,7 +626,6 @@ class ImageHelper final : public CommandGraphResource
VkImageAspectFlags clearAspectFlags,
const VkClearDepthStencilValue &depthStencil,
CommandBufferT *commandBuffer);
gl::Extents getSize(const gl::ImageIndex &index) const;
static void Copy(ImageHelper *srcImage,
......
......@@ -180,9 +180,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
const VkBufferMemoryBarrier *bufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier *imageMemoryBarriers);
void imageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkImageMemoryBarrier *imageMemoryBarrier);
void clearColorImage(const Image &image,
VkImageLayout imageLayout,
const VkClearColorValue &color,
......@@ -228,21 +226,16 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance);
void draw(uint32_t vertexCount, uint32_t firstVertex);
void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
void drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance);
void drawIndexed(uint32_t indexCount);
void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
void bindPipeline(VkPipelineBindPoint pipelineBindPoint, const Pipeline &pipeline);
void bindGraphicsPipeline(const Pipeline &pipeline);
void bindComputePipeline(const Pipeline &pipeline);
void bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
......@@ -580,15 +573,6 @@ ANGLE_INLINE void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMa
imageMemoryBarrierCount, imageMemoryBarriers);
}
ANGLE_INLINE void CommandBuffer::imageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkImageMemoryBarrier *imageMemoryBarrier)
{
ASSERT(valid());
vkCmdPipelineBarrier(mHandle, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1,
imageMemoryBarrier);
}
ANGLE_INLINE void CommandBuffer::destroy(VkDevice device)
{
releaseHandle();
......@@ -824,20 +808,6 @@ ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount,
vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, firstInstance);
}
ANGLE_INLINE void CommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
{
ASSERT(valid());
vkCmdDraw(mHandle, vertexCount, 1, firstVertex, 0);
}
ANGLE_INLINE void CommandBuffer::drawInstanced(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex)
{
ASSERT(valid());
vkCmdDraw(mHandle, vertexCount, instanceCount, firstVertex, 0);
}
ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
......@@ -848,18 +818,6 @@ ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount,
vkCmdDrawIndexed(mHandle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
ANGLE_INLINE void CommandBuffer::drawIndexed(uint32_t indexCount)
{
ASSERT(valid());
vkCmdDrawIndexed(mHandle, indexCount, 1, 0, 0, 0);
}
ANGLE_INLINE void CommandBuffer::drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount)
{
ASSERT(valid());
vkCmdDrawIndexed(mHandle, indexCount, instanceCount, 0, 0, 0);
}
ANGLE_INLINE void CommandBuffer::dispatch(uint32_t groupCountX,
uint32_t groupCountY,
uint32_t groupCountZ)
......@@ -875,18 +833,6 @@ ANGLE_INLINE void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPo
vkCmdBindPipeline(mHandle, pipelineBindPoint, pipeline.getHandle());
}
ANGLE_INLINE void CommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
{
ASSERT(valid() && pipeline.valid());
vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getHandle());
}
ANGLE_INLINE void CommandBuffer::bindComputePipeline(const Pipeline &pipeline)
{
ASSERT(valid() && pipeline.valid());
vkCmdBindPipeline(mHandle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getHandle());
}
ANGLE_INLINE void CommandBuffer::bindVertexBuffers(uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *buffers,
......
......@@ -1404,8 +1404,6 @@ TEST_P(SimpleStateChangeTest, RedefineBufferInUse)
// Tests updating a buffer's contents while in use, without redefining it.
TEST_P(SimpleStateChangeTest, UpdateBufferInUse)
{
// tobine: Started failing w/ custom cmd buffers. http://anglebug.com/3255
ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
std::vector<GLColor> redColorData(6, GLColor::red);
GLBuffer buffer;
......
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