CommandBufferVk.h#
The CommandBuffer class, arguably the busiest class in Vulkan, containing most functionality.
Includes#
PVRVk/ComputePipelineVk.h
PVRVk/DescriptorSetVk.h
PVRVk/DeviceVk.h
PVRVk/EventVk.h
PVRVk/FramebufferVk.h
PVRVk/GraphicsPipelineVk.h
PVRVk/MemoryBarrierVk.h
PVRVk/RaytracingPipelineVk.h
PVRVk/RenderPassVk.h
Included By#
Namespaces#
Classes#
Source Code#
#pragma once
#include "PVRVk/DeviceVk.h"
#include "PVRVk/DescriptorSetVk.h"
#include "PVRVk/GraphicsPipelineVk.h"
#include "PVRVk/ComputePipelineVk.h"
#include "PVRVk/RaytracingPipelineVk.h"
#include "PVRVk/MemoryBarrierVk.h"
#include "PVRVk/EventVk.h"
#include "PVRVk/FramebufferVk.h"
#include "PVRVk/RenderPassVk.h"
namespace pvrvk {
namespace impl {
class CommandBufferBase_ : public PVRVkDeviceObjectBase<VkCommandBuffer, ObjectType::e_COMMAND_BUFFER>, public DeviceObjectDebugUtils<CommandBufferBase_>
{
protected:
class make_shared_enabler
{
protected:
make_shared_enabler() = default;
friend class CommandBufferBase_;
};
static CommandBufferBase constructShared(const DeviceWeakPtr& device, CommandPool& pool, VkCommandBuffer myHandle)
{
return std::make_shared<CommandBufferBase_>(make_shared_enabler{}, device, pool, myHandle);
}
std::vector<std::shared_ptr<void> > _objectReferences;
CommandPool _pool;
bool _isRecording;
bool _VKSynchronization2IsSupported;
public:
DECLARE_NO_COPY_SEMANTICS(CommandBufferBase_)
CommandBufferBase_(make_shared_enabler, const DeviceWeakPtr& device, CommandPool pool, VkCommandBuffer myHandle)
: PVRVkDeviceObjectBase(device, myHandle), DeviceObjectDebugUtils(), _pool(pool), _isRecording(false), _VKSynchronization2IsSupported(false)
{}
virtual ~CommandBufferBase_();
void begin(const CommandBufferUsageFlags flags = CommandBufferUsageFlags(0));
void end();
void beginDebugUtilsLabel(const pvrvk::DebugUtilsLabel& labelInfo)
{
VkDebugUtilsLabelEXT vkLabelInfo = {};
vkLabelInfo.sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_LABEL_EXT);
// The color to use for the marked region
vkLabelInfo.color[0] = labelInfo.getR();
vkLabelInfo.color[1] = labelInfo.getG();
vkLabelInfo.color[2] = labelInfo.getB();
vkLabelInfo.color[3] = labelInfo.getA();
// The label name to give to the marked region
vkLabelInfo.pLabelName = labelInfo.getLabelName().c_str();
getDevice()->getPhysicalDevice()->getInstance()->getVkBindings().vkCmdBeginDebugUtilsLabelEXT(getVkHandle(), &vkLabelInfo);
}
void endDebugUtilsLabel() { getDevice()->getPhysicalDevice()->getInstance()->getVkBindings().vkCmdEndDebugUtilsLabelEXT(getVkHandle()); }
void insertDebugUtilsLabel(const pvrvk::DebugUtilsLabel& labelInfo)
{
VkDebugUtilsLabelEXT vkLabelInfo = {};
vkLabelInfo.sType = static_cast<VkStructureType>(StructureType::e_DEBUG_UTILS_LABEL_EXT);
// The color to use for the marked region
vkLabelInfo.color[0] = labelInfo.getR();
vkLabelInfo.color[1] = labelInfo.getG();
vkLabelInfo.color[2] = labelInfo.getB();
vkLabelInfo.color[3] = labelInfo.getA();
// The label name to give to the marked region
vkLabelInfo.pLabelName = labelInfo.getLabelName().c_str();
getDevice()->getPhysicalDevice()->getInstance()->getVkBindings().vkCmdInsertDebugUtilsLabelEXT(getVkHandle(), &vkLabelInfo);
}
void debugMarkerBeginEXT(pvrvk::DebugMarkerMarkerInfo& markerInfo)
{
VkDebugMarkerMarkerInfoEXT vkMarkerInfo = {};
vkMarkerInfo.sType = static_cast<VkStructureType>(StructureType::e_DEBUG_MARKER_MARKER_INFO_EXT);
// The color to use for the marked region
vkMarkerInfo.color[0] = markerInfo.getR();
vkMarkerInfo.color[1] = markerInfo.getG();
vkMarkerInfo.color[2] = markerInfo.getB();
vkMarkerInfo.color[3] = markerInfo.getA();
// The name to give to the marked region
vkMarkerInfo.pMarkerName = markerInfo.getMarkerName().c_str();
getDevice()->getVkBindings().vkCmdDebugMarkerBeginEXT(getVkHandle(), &vkMarkerInfo);
}
void debugMarkerEndEXT() { getDevice()->getVkBindings().vkCmdDebugMarkerEndEXT(getVkHandle()); }
void debugMarkerInsertEXT(pvrvk::DebugMarkerMarkerInfo& markerInfo)
{
VkDebugMarkerMarkerInfoEXT vkMarkerInfo = {};
vkMarkerInfo.sType = static_cast<VkStructureType>(StructureType::e_DEBUG_MARKER_MARKER_INFO_EXT);
// The color to use for the marked region
vkMarkerInfo.color[0] = markerInfo.getR();
vkMarkerInfo.color[1] = markerInfo.getG();
vkMarkerInfo.color[2] = markerInfo.getB();
vkMarkerInfo.color[3] = markerInfo.getA();
// The name to give to the marked region
vkMarkerInfo.pMarkerName = markerInfo.getMarkerName().c_str();
getDevice()->getVkBindings().vkCmdDebugMarkerInsertEXT(getVkHandle(), &vkMarkerInfo);
}
void resetQueryPool(QueryPool& queryPool, uint32_t firstQuery, uint32_t queryCount);
void resetQueryPool(QueryPool& queryPool, uint32_t queryIndex);
void beginQuery(QueryPool& queryPool, uint32_t queryIndex, QueryControlFlags flags = QueryControlFlags(0));
void endQuery(QueryPool& queryPool, uint32_t queryIndex);
void copyQueryPoolResults(QueryPool& queryPool, uint32_t firstQuery, uint32_t queryCount, Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize stride, QueryResultFlags flags);
void writeTimestamp(QueryPool& queryPool, uint32_t queryIndex, PipelineStageFlags pipelineStage);
bool isRecording() { return _isRecording; }
void bindPipeline(const GraphicsPipeline& pipeline)
{
_objectReferences.emplace_back(pipeline);
getDevice()->getVkBindings().vkCmdBindPipeline(getVkHandle(), static_cast<VkPipelineBindPoint>(PipelineBindPoint::e_GRAPHICS), pipeline->getVkHandle());
}
void bindPipeline(ComputePipeline& pipeline)
{
_objectReferences.emplace_back(pipeline);
getDevice()->getVkBindings().vkCmdBindPipeline(getVkHandle(), static_cast<VkPipelineBindPoint>(PipelineBindPoint::e_COMPUTE), pipeline->getVkHandle());
}
void bindPipeline(RaytracingPipeline& pipeline)
{
_objectReferences.emplace_back(pipeline);
getDevice()->getVkBindings().vkCmdBindPipeline(getVkHandle(), static_cast<VkPipelineBindPoint>(PipelineBindPoint::e_RAY_TRACING_KHR), pipeline->getVkHandle());
}
void bindDescriptorSets(PipelineBindPoint bindingPoint, const PipelineLayout& pipelineLayout, uint32_t firstSet, const DescriptorSet* sets, uint32_t numDescriptorSets,
const uint32_t* dynamicOffsets = nullptr, uint32_t numDynamicOffsets = 0);
void bindDescriptorSet(PipelineBindPoint bindingPoint, const PipelineLayout& pipelineLayout, uint32_t firstSet, const DescriptorSet set,
const uint32_t* dynamicOffsets = nullptr, uint32_t numDynamicOffsets = 0)
{
bindDescriptorSets(bindingPoint, pipelineLayout, firstSet, &set, 1, dynamicOffsets, numDynamicOffsets);
}
void bindVertexBuffers(const Buffer* buffers, uint32_t firstBinding, uint16_t bindingCount, const uint32_t* offsets = nullptr)
{
VkBuffer native_buffers[static_cast<uint32_t>(FrameworkCaps::MaxVertexBindings)] = { VK_NULL_HANDLE };
for (uint32_t i = 0; i < bindingCount; ++i)
{
_objectReferences.emplace_back(buffers[i]);
native_buffers[i] = buffers[i]->getVkHandle();
}
getDevice()->getVkBindings().vkCmdBindVertexBuffers(getVkHandle(), firstBinding, bindingCount, native_buffers, (VkDeviceSize*)offsets);
}
void bindVertexBuffer(const Buffer& buffer, uint32_t offset, uint16_t bindingIndex)
{
_objectReferences.emplace_back(buffer);
VkDeviceSize offs = offset;
getDevice()->getVkBindings().vkCmdBindVertexBuffers(getVkHandle(), bindingIndex, !!buffer, (buffer ? &buffer->getVkHandle() : NULL), &offs);
}
void bindVertexBuffer(Buffer const* buffers, uint32_t* offsets, uint16_t numBuffers, uint16_t startBinding, uint16_t numBindings);
void bindIndexBuffer(const Buffer& buffer, uint32_t offset, IndexType indexType)
{
_objectReferences.emplace_back(buffer);
getDevice()->getVkBindings().vkCmdBindIndexBuffer(getVkHandle(), buffer->getVkHandle(), offset, static_cast<VkIndexType>(indexType));
}
void pipelineBarrier(PipelineStageFlags srcStage, PipelineStageFlags dstStage, const MemoryBarrierSet& barriers, bool dependencyByRegion = true);
void pipelineBarrier2(const MemoryBarrierSet2& barriers, bool dependencyByRegion = true);
void waitForEvent(const Event& event, PipelineStageFlags srcStage, PipelineStageFlags dstStage, const MemoryBarrierSet& barriers);
void waitForEvents(const Event* events, uint32_t numEvents, PipelineStageFlags srcStage, PipelineStageFlags dstStage, const MemoryBarrierSet& barriers);
void setEvent(Event& event, PipelineStageFlags pipelineStageFlags = PipelineStageFlags::e_ALL_COMMANDS_BIT)
{
_objectReferences.emplace_back(event);
getDevice()->getVkBindings().vkCmdSetEvent(getVkHandle(), event->getVkHandle(), static_cast<VkPipelineStageFlags>(pipelineStageFlags));
}
void resetEvent(Event& event, PipelineStageFlags pipelineStageFlags = PipelineStageFlags::e_ALL_COMMANDS_BIT)
{
getDevice()->getVkBindings().vkCmdResetEvent(getVkHandle(), event->getVkHandle(), static_cast<VkPipelineStageFlags>(pipelineStageFlags));
}
void reset(CommandBufferResetFlags resetFlags = CommandBufferResetFlags::e_NONE)
{
_objectReferences.clear();
getDevice()->getVkBindings().vkResetCommandBuffer(getVkHandle(), static_cast<VkCommandBufferResetFlagBits>(resetFlags));
}
void copyImage(const Image& srcImage, const Image& dstImage, ImageLayout srcImageLayout, ImageLayout dstImageLayout, uint32_t numRegions, const ImageCopy* regions);
void copyImageToBuffer(const Image& srcImage, ImageLayout srcImageLayout, Buffer& dstBuffer, const BufferImageCopy* regions, uint32_t numRegions);
void copyBuffer(const Buffer& srcBuffer, const Buffer& dstBuffer, uint32_t numRegions, const BufferCopy* regions);
void copyBufferToImage(const Buffer& buffer, const Image& image, ImageLayout dstImageLayout, uint32_t regionsCount, const BufferImageCopy* regions);
void fillBuffer(const Buffer& dstBuffer, uint32_t dstOffset, uint32_t data, uint64_t size = VK_WHOLE_SIZE);
void setViewport(const Viewport& viewport);
void clearAttachments(const uint32_t numAttachments, const ClearAttachment* clearAttachments, uint32_t numRectangles, const ClearRect* clearRectangles);
void clearAttachment(const ClearAttachment& clearAttachment, const ClearRect& clearRectangle) { clearAttachments(1, &clearAttachment, 1, &clearRectangle); }
void draw(uint32_t firstVertex, uint32_t numVertices, uint32_t firstInstance = 0, uint32_t numInstances = 1);
void drawIndexed(uint32_t firstIndex, uint32_t numIndices, int32_t vertexOffset = 0, uint32_t firstInstance = 0, uint32_t numInstances = 1);
void drawIndirect(const Buffer& buffer, uint32_t offset, uint32_t count, uint32_t stride);
void drawIndexedIndirect(const Buffer& buffer, uint32_t offset, uint32_t count, uint32_t stride);
void dispatch(uint32_t numGroupX, uint32_t numGroupY, uint32_t numGroupZ);
void dispatchIndirect(Buffer& buffer, uint32_t offset);
void clearColorImage(const ImageView& image, const ClearColorValue& clearColor, ImageLayout currentLayout, const uint32_t baseMipLevel = 0, const uint32_t numLevels = 1,
const uint32_t baseArrayLayer = 0, const uint32_t numLayers = 1);
void clearColorImage(const ImageView& image, const ClearColorValue& clearColor, ImageLayout currentLayout, const uint32_t* baseMipLevels, const uint32_t* numLevels,
const uint32_t* baseArrayLayers, const uint32_t* numLayers, uint32_t numRanges);
void clearDepthStencilImage(const Image& image, float clearDepth, uint32_t clearStencil, const uint32_t baseMipLevel, const uint32_t numLevels, const uint32_t baseArrayLayer,
const uint32_t numLayers, ImageLayout layout);
void clearDepthStencilImage(const Image& image, float clearDepth, uint32_t clearStencil, const uint32_t* baseMipLevels, const uint32_t* numLevels,
const uint32_t* baseArrayLayers, const uint32_t* numLayers, uint32_t numRanges, ImageLayout layout);
void clearStencilImage(const Image& image, uint32_t clearStencil, const uint32_t baseMipLevel, const uint32_t numLevels, const uint32_t baseArrayLayer,
const uint32_t numLayers, ImageLayout layout);
void clearStencilImage(const Image& image, uint32_t clearStencil, const uint32_t* baseMipLevels, const uint32_t* numLevels, const uint32_t* baseArrayLayers,
const uint32_t* numLayers, uint32_t numRanges, ImageLayout layout);
void clearDepthImage(
const Image& image, float clearDepth, const uint32_t baseMipLevel, const uint32_t numLevels, const uint32_t baseArrayLayer, const uint32_t numLayers, ImageLayout layout);
void clearDepthImage(const Image& image, float clearDepth, const uint32_t* baseMipLevels, const uint32_t* numLevels, const uint32_t* baseArrayLayers, const uint32_t* numLayers,
uint32_t numRanges, ImageLayout layout);
void setScissor(uint32_t firstScissor, uint32_t numScissors, const Rect2D* scissors);
void setDepthBounds(float min, float max);
void setStencilWriteMask(StencilFaceFlags face, uint32_t writeMask);
void setStencilReference(StencilFaceFlags face, uint32_t reference);
void setStencilCompareMask(StencilFaceFlags face, uint32_t compareMask);
void setDepthBias(float constantFactor, float clamp, float slopeFactor);
void setBlendConstants(float rgba[4]);
void setLineWidth(float lineWidth);
void blitImage(const Image& srcImage, const Image& dstImage, const ImageBlit* regions, uint32_t numRegions, Filter filter, ImageLayout srcLayout, ImageLayout dstLayout);
void resolveImage(const Image& srcImage, const Image& dstImage, const ImageResolve* regions, uint32_t numRegions, ImageLayout srcLayout, ImageLayout dstLayout);
void updateBuffer(const Buffer& buffer, const void* data, uint32_t offset, uint32_t length);
void pushConstants(const PipelineLayout& pipelineLayout, ShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* data);
void bindTransformFeedbackBuffers(pvrvk::Buffer buffer, VkDeviceSize offset, VkDeviceSize size = VK_WHOLE_SIZE);
void bindTransformFeedbackBuffers(uint32_t firstBinding, uint32_t bindingCount, const pvrvk::Buffer* buffers, const VkDeviceSize* offsets, const VkDeviceSize* sizes = nullptr);
void beginTransformFeedback(
uint32_t firstCounterBuffer, uint32_t numCounterBuffers, const pvrvk::Buffer* counterBuffers = nullptr, const VkDeviceSize* counterBufferOffsets = nullptr);
void beginTransformFeedback(pvrvk::Buffer counterBuffer, VkDeviceSize counterBufferOffset = 0);
void endTransformFeedback(uint32_t firstCounterBuffer, uint32_t numCounterBuffers, const pvrvk::Buffer* counterBuffers = nullptr, const VkDeviceSize* counterBufferOffsets = nullptr);
void endTransformFeedback(pvrvk::Buffer counterBuffer, VkDeviceSize counterBufferOffset = 0);
void beginQueryIndexed(QueryPool& queryPool, uint32_t queryIndex, QueryControlFlags flags = QueryControlFlags(0), uint32_t index = 0);
void endQueryIndexed(QueryPool& queryPool, uint32_t queryIndex, uint32_t index = 0);
void drawIndirectByteCount(
uint32_t instanceCount, uint32_t firstInstance, pvrvk::Buffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride);
const CommandPool getCommandPool() const { return _pool; }
void setFragmentShadingRate(Extent2D fragmentSize, FragmentShadingRateCombinerOpKHR combinerOpPipelinePrimitive, FragmentShadingRateCombinerOpKHR combinerOpResultAttachment);
void traceRays(pvrvk::StridedDeviceAddressRegionKHR& raygenTable, pvrvk::StridedDeviceAddressRegionKHR& missTable, pvrvk::StridedDeviceAddressRegionKHR& hitTable,
pvrvk::StridedDeviceAddressRegionKHR& callableTable, int width, int height, int depth)
{
VkStridedDeviceAddressRegionKHR raygen = VkStridedDeviceAddressRegionKHR{ raygenTable.getDeviceAddress(), raygenTable.getStride(), raygenTable.getSize() };
VkStridedDeviceAddressRegionKHR miss = VkStridedDeviceAddressRegionKHR{ missTable.getDeviceAddress(), missTable.getStride(), missTable.getSize() };
VkStridedDeviceAddressRegionKHR hit = VkStridedDeviceAddressRegionKHR{ hitTable.getDeviceAddress(), hitTable.getStride(), hitTable.getSize() };
VkStridedDeviceAddressRegionKHR callable = VkStridedDeviceAddressRegionKHR{ callableTable.getDeviceAddress(), callableTable.getStride(), callableTable.getSize() };
getDevice()->getVkBindings().vkCmdTraceRaysKHR(getVkHandle(), &raygen, &miss, &hit, &callable, width, height, depth);
}
void setVKSynchronization2IsSupported(bool value)
{
_VKSynchronization2IsSupported = value;
}
};
class CommandBuffer_ : public CommandBufferBase_
{
protected:
friend class CommandPool_;
class make_shared_enabler : public CommandBufferBase_::make_shared_enabler
{
protected:
make_shared_enabler() : CommandBufferBase_::make_shared_enabler() {}
friend CommandBuffer_;
};
static CommandBuffer constructShared(const DeviceWeakPtr& device, CommandPool pool, VkCommandBuffer myHandle)
{
return std::make_shared<CommandBuffer_>(make_shared_enabler{}, device, pool, myHandle);
}
#ifdef DEBUG
pvrvk::Framebuffer _currentlyBoundFramebuffer;
uint32_t _currentSubpass;
#endif
public:
DECLARE_NO_COPY_SEMANTICS(CommandBuffer_)
CommandBuffer_(make_shared_enabler, const DeviceWeakPtr& device, CommandPool pool, VkCommandBuffer myHandle)
: CommandBufferBase_(make_shared_enabler{}, device, pool, myHandle)
#ifdef DEBUG
,
_currentSubpass(static_cast<uint32_t>(-1))
#endif
{}
virtual ~CommandBuffer_()
{
#ifdef DEBUG
_currentlyBoundFramebuffer.reset();
#endif
}
void executeCommands(const SecondaryCommandBuffer& secondaryCmdBuffer);
void executeCommands(const SecondaryCommandBuffer* secondaryCmdBuffers, uint32_t numCommandBuffers);
void beginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Rect2D& renderArea, bool inlineFirstSubpass = false,
const ClearValue* clearValues = nullptr, uint32_t numClearValues = 0);
void beginRenderPass(const Framebuffer& framebuffer, const Rect2D& renderArea, bool inlineFirstSubpass = false, const ClearValue* clearValues = nullptr, uint32_t numClearValues = 0);
void beginRenderPass(const Framebuffer& framebuffer, bool inlineFirstSubpass = false, const ClearValue* clearValues = nullptr, uint32_t numClearValues = 0);
void endRenderPass()
{
getDevice()->getVkBindings().vkCmdEndRenderPass(getVkHandle());
#ifdef DEBUG
auto& currentRenderPass = _currentlyBoundFramebuffer->getCreateInfo().getRenderPass();
assert(currentRenderPass->getCreateInfo().getNumAttachmentDescription() == _currentlyBoundFramebuffer->getNumAttachments());
for (uint32_t i = 0; i < _currentlyBoundFramebuffer->getNumAttachments(); ++i)
{ _currentlyBoundFramebuffer->getAttachment(i)->getImage()->setImageLayout(currentRenderPass->getCreateInfo().getAttachmentDescription(i).getFinalLayout()); }
_currentlyBoundFramebuffer.reset();
_currentSubpass = static_cast<uint32_t>(-1);
#endif
}
#ifdef DEBUG
void updatePerSubpassImageLayouts()
{
auto& currentRenderPass = _currentlyBoundFramebuffer->getCreateInfo().getRenderPass();
for (uint8_t i = 0; i < currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getNumInputAttachmentReference(); ++i)
{
const AttachmentReference& attachmentReference = currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getInputAttachmentReference(i);
_currentlyBoundFramebuffer->getCreateInfo().getAttachment(attachmentReference.getAttachment())->getImage()->setImageLayout(attachmentReference.getLayout());
}
for (uint8_t i = 0; i < currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getNumColorAttachmentReference(); ++i)
{
const AttachmentReference& attachmentReference = currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getColorAttachmentReference(i);
_currentlyBoundFramebuffer->getCreateInfo().getAttachment(attachmentReference.getAttachment())->getImage()->setImageLayout(attachmentReference.getLayout());
}
for (uint8_t i = 0; i < currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getNumResolveAttachmentReference(); ++i)
{
const AttachmentReference& attachmentReference = currentRenderPass->getCreateInfo().getSubpass(_currentSubpass).getResolveAttachmentReference(i);
_currentlyBoundFramebuffer->getCreateInfo().getAttachment(attachmentReference.getAttachment())->getImage()->setImageLayout(attachmentReference.getLayout());
}
}
#endif
void nextSubpass(SubpassContents contents)
{
getDevice()->getVkBindings().vkCmdNextSubpass(getVkHandle(), static_cast<VkSubpassContents>(contents));
#ifdef DEBUG
_currentSubpass++;
updatePerSubpassImageLayouts();
#endif
}
};
class SecondaryCommandBuffer_ : public CommandBufferBase_
{
protected:
friend class CommandPool_;
class make_shared_enabler : public CommandBufferBase_::make_shared_enabler
{
protected:
make_shared_enabler() : CommandBufferBase_::make_shared_enabler() {}
friend SecondaryCommandBuffer_;
};
static SecondaryCommandBuffer constructShared(const DeviceWeakPtr& device, CommandPool pool, VkCommandBuffer myHandle)
{
return std::make_shared<SecondaryCommandBuffer_>(make_shared_enabler{}, device, pool, myHandle);
}
public:
DECLARE_NO_COPY_SEMANTICS(SecondaryCommandBuffer_)
SecondaryCommandBuffer_(make_shared_enabler, const DeviceWeakPtr& device, CommandPool pool, VkCommandBuffer myHandle)
: CommandBufferBase_(make_shared_enabler{}, device, pool, myHandle)
{}
using CommandBufferBase_::begin;
void begin(const RenderPass& renderpass, uint32_t subpass = 0, const CommandBufferUsageFlags flags = CommandBufferUsageFlags::e_RENDER_PASS_CONTINUE_BIT);
void begin(const Framebuffer& framebuffer, uint32_t subpass = 0, const CommandBufferUsageFlags flags = CommandBufferUsageFlags::e_RENDER_PASS_CONTINUE_BIT);
};
} // namespace impl
} // namespace pvrvk