This commit is contained in:
Brandon Mak 2022-09-25 23:25:51 +08:00
parent fc5ff763f3
commit dc6289e8cf
6 changed files with 161 additions and 124 deletions

View File

@ -40,8 +40,8 @@ namespace Sandbox
// Create Stress Test Objects
static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f };
constexpr int NUM_ROWS = 200;
constexpr int NUM_COLS = 100;
constexpr int NUM_ROWS = 1;
constexpr int NUM_COLS = 1;
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
for (int z = 0; z < NUM_ROWS; ++z)

View File

@ -16,7 +16,7 @@ namespace SHADE
{
/***************************************************************************/
/*!
\brief
Frees the command buffer.
@ -30,13 +30,13 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Only the command buffer is allocated using
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting
Only the command buffer is allocated using
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting
individually permitted. Otherwise, throw exception. IMPORTANT NOTE:
the command buffer cannot be in the pending state!!!
*/
/***************************************************************************/
void SHVkCommandBuffer::Reset(void)
@ -67,10 +67,10 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Begins the command buffer.
*/
/***************************************************************************/
void SHVkCommandBuffer::BeginRecording(void) noexcept
@ -108,10 +108,10 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
End the recording of a command buffer.
*/
/***************************************************************************/
void SHVkCommandBuffer::EndRecording(void) noexcept
@ -121,21 +121,21 @@ namespace SHADE
SHLOG_ERROR("Command Buffer not in recording state, cannot end recording. ");
return;
}
vkCommandBuffer.end();
cmdBufferState = SH_CMD_BUFFER_STATE::EXECUTABLE;
}
/***************************************************************************/
/*!
\brief
Begins a renderpass in the command buffer. 2 important things to note
here, the command buffer used MUST be a primary command buffer and
Begins a renderpass in the command buffer. 2 important things to note
here, the command buffer used MUST be a primary command buffer and
command buffer MUST be in a recording state.
\param renderpassHdl
Renderpass for obvious reasons.
Renderpass for obvious reasons.
\param framebufferHdl
Framebuffer required in the begin info.
@ -145,7 +145,7 @@ namespace SHADE
\param extent
Extent of the render area in the framebuffer.
*/
/***************************************************************************/
void SHVkCommandBuffer::BeginRenderpass(Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset, vk::Extent2D extent) noexcept
@ -170,7 +170,7 @@ namespace SHADE
vk::RenderPassBeginInfo renderPassInfo{};
renderPassInfo.renderPass = renderpassHdl->GetVkRenderpass();
renderPassInfo.framebuffer = framebufferHdl->GetVkFramebuffer();
// If the extent passed in is 0, use the framebuffer dimensions instead.
if (extent.width == 0 && extent.height == 0)
renderPassInfo.renderArea.extent = framebufferExtent;
@ -192,16 +192,16 @@ namespace SHADE
}
// Begin the render pass
vkCommandBuffer.beginRenderPass (&renderPassInfo, vk::SubpassContents::eInline);
vkCommandBuffer.beginRenderPass(&renderPassInfo, vk::SubpassContents::eInline);
}
/***************************************************************************/
/*!
\brief
Ends a renderpass.
*/
/***************************************************************************/
void SHVkCommandBuffer::EndRenderpass(void) noexcept
@ -216,14 +216,14 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Sets the viewport dynamically for the command buffer. #NoteToSelf:
Dynamic state will not affect pipelines that don't use dynamic state
so there isn't a need to do any checks. Also, setting dynamic state like
this only needs to happen ONCE per command buffer UNLESS a different
viewport is to be used for different drawing commands.
\param vpWidth
viewport width
@ -254,7 +254,7 @@ namespace SHADE
\param vpMaxDepth
viewport maximum depth value
*/
/***************************************************************************/
void SHVkCommandBuffer::SetViewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept
@ -283,13 +283,13 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Binds a pipeline object to the command buffer.
\param pipelineHdl
The pipeline to bind.
*/
/***************************************************************************/
void SHVkCommandBuffer::BindPipeline(Handle<SHVkPipeline> const& pipelineHdl) noexcept
@ -307,7 +307,7 @@ namespace SHADE
/*!
\brief
Binds a buffer to the vertex buffer binding point specified in
Binds a buffer to the vertex buffer binding point specified in
bindingPoint.
\param bindingPoint
@ -321,29 +321,32 @@ namespace SHADE
*/
/***************************************************************************/
void SHVkCommandBuffer::BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
void SHVkCommandBuffer::BindVertexBuffer(uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
{
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
{
auto bufferHandle = buffer->GetVkBuffer();
vkCommandBuffer.bindVertexBuffers (bindingPoint, 1, &bufferHandle, &offset);
if (buffer)
{
auto bufferHandle = buffer->GetVkBuffer();
vkCommandBuffer.bindVertexBuffers(bindingPoint, 1, &bufferHandle, &offset);
}
}
}
/***************************************************************************/
/*!
\brief
Binds an index buffer to the pipeline.
\param buffer
The buffer to bind.
\param startingIndex
The starting index in the index buffer. For example, 0 would mean
starting at the beginning. 5 would mean starting at byte offset
The starting index in the index buffer. For example, 0 would mean
starting at the beginning. 5 would mean starting at byte offset
size(uint32_t) * 5.
*/
/***************************************************************************/
void SHVkCommandBuffer::BindIndexBuffer(Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept
@ -351,33 +354,33 @@ namespace SHADE
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
{
auto bufferHandle = buffer->GetVkBuffer();
vkCommandBuffer.bindIndexBuffer (bufferHandle, sizeof (uint32_t) * startingIndex, vk::IndexType::eUint32);
vkCommandBuffer.bindIndexBuffer(bufferHandle, sizeof(uint32_t) * startingIndex, vk::IndexType::eUint32);
}
}
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
{
vkCommandBuffer.bindDescriptorSets (bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
}
/***************************************************************************/
/*!
\brief
Calls vkCmdDraw.
\param vertexCount
How many vertices to draw
\param instanceCount
Number of instances to draw
\param firstVertex
First vertex in the buffer of vertices to start from
\param firstInstance
First instance to start from.
*/
/***************************************************************************/
void SHVkCommandBuffer::DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept
@ -387,30 +390,30 @@ namespace SHADE
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
return;
}
vkCommandBuffer.draw (vertexCount, instanceCount, firstVertex, firstInstance);
vkCommandBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance);
}
/***************************************************************************/
/*!
\brief
Issues a non-instanced indexed draw call.
\param indexCount
Number of indices to draw.
\param firstIndex
Starting index. if the array was 0, 2, 5, 4, and we indicated this to be
1. The draw call would start from index 2.
1. The draw call would start from index 2.
\param vertexOffset
Starting vertex offset. This would indicate that vertex pulling should
Starting vertex offset. This would indicate that vertex pulling should
start from a certain vertex. So a vertex offset of 3 (for example) would
mean an index of 0 would mean the 3rd vertex.
*/
/***************************************************************************/
void SHVkCommandBuffer::DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept
void SHVkCommandBuffer::DrawIndexed(uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept
{
if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING)
{
@ -422,7 +425,7 @@ namespace SHADE
vkCommandBuffer.drawIndexed(indexCount, 1, firstIndex, vertexOffset, 0);
}
/***************************************************************************/
/*!
@ -445,35 +448,36 @@ namespace SHADE
return;
}
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
if (indirectDrawData)
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
}
void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
{
vkCommandBuffer.copyBufferToImage
(
src, dst, vk::ImageLayout::eTransferDstOptimal,
static_cast<uint32_t>(copyInfo.size()), copyInfo.data()
);
vkCommandBuffer.copyBufferToImage
(
src, dst, vk::ImageLayout::eTransferDstOptimal,
static_cast<uint32_t>(copyInfo.size()), copyInfo.data()
);
}
void SHVkCommandBuffer::PipelineBarrier(
vk::PipelineStageFlags srcStage,
vk::PipelineStageFlags dstStage,
vk::DependencyFlags deps,
std::vector<vk::MemoryBarrier> const& memoryBarriers,
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
) const noexcept
vk::PipelineStageFlags srcStage,
vk::PipelineStageFlags dstStage,
vk::DependencyFlags deps,
std::vector<vk::MemoryBarrier> const& memoryBarriers,
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
) const noexcept
{
vkCommandBuffer.pipelineBarrier (
srcStage,
dstStage,
deps,
memoryBarriers,
bufferMemoryBarriers,
imageMemoryBarriers
);
vkCommandBuffer.pipelineBarrier(
srcStage,
dstStage,
deps,
memoryBarriers,
bufferMemoryBarriers,
imageMemoryBarriers
);
}
bool SHVkCommandBuffer::IsReadyToSubmit(void) const noexcept
@ -498,10 +502,10 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Calls vkCmdPushConstants and submits data stored in command buffer.
*/
/***************************************************************************/
void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept
@ -514,13 +518,13 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Simply returns the command buffer handle.
\return
\return
The command buffer handle.
*/
/***************************************************************************/
vk::CommandBuffer const& SHVkCommandBuffer::GetVkCommandBuffer(void) const noexcept
@ -530,11 +534,11 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html
See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html
or look up vkGetRenderAreaGranularity.
\param renderpassHdl
Renderpass to get info from.
@ -544,9 +548,9 @@ namespace SHADE
\param renderArea
For the comparison. Again, look it up on the webpage.
\return
\return
If optimal, true. otherwise false.
*/
/***************************************************************************/
bool SHVkCommandBuffer::IsRenderAreaOptimal(Handle<SHVkRenderpass> const& renderpassHdl, vk::Extent2D const& framebufferExtent, vk::Rect2D const& renderArea) const noexcept
@ -558,14 +562,14 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Setter for the state of the command buffer.
\param state
\return
\return
*/
/***************************************************************************/
void SHVkCommandBuffer::SetState(SH_CMD_BUFFER_STATE state) noexcept
@ -575,12 +579,12 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Returns the state of the command buffer.
\return
\return
*/
/***************************************************************************/
SH_CMD_BUFFER_STATE SHVkCommandBuffer::GetState(void) const noexcept
@ -590,14 +594,14 @@ namespace SHADE
/***************************************************************************/
/*!
\brief
Creates a command buffer. Cmd buffer can be primary or secondary. If
secondary, flags will automatically have renderpass continue bit. Command
pool used to create this command buffer will determine whether or not
this buffer will be allocated with
this buffer will be allocated with
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT using the reset mode.
\param logicalDevice
Need a logical device to create a buffer.
@ -606,7 +610,7 @@ namespace SHADE
\param type
Type of the command buffer; primary or secondary.
*/
/***************************************************************************/
SHVkCommandBuffer::SHVkCommandBuffer(Handle<SHVkCommandPool> const& commandPool, SH_CMD_BUFFER_TYPE type) noexcept
@ -616,7 +620,7 @@ namespace SHADE
, parentPoolResetMode{ SH_CMD_POOL_RESET::POOL_BASED }
, usageFlags{}
, commandBufferCount{ 0 }
, parentPool{commandPool}
, parentPool{ commandPool }
, pushConstantData{}
{
@ -657,54 +661,54 @@ namespace SHADE
commandBufferType = type;
commandBufferCount = allocateInfo.commandBufferCount;
if (parentPool->GetIsTransient ())
if (parentPool->GetIsTransient())
usageFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
if (commandBufferType == SH_CMD_BUFFER_TYPE::SECONDARY)
usageFlags |= vk::CommandBufferUsageFlagBits::eRenderPassContinue;
// Reset all the push constant data to 0
memset (pushConstantData, 0, PUSH_CONSTANT_SIZE);
memset(pushConstantData, 0, PUSH_CONSTANT_SIZE);
}
/***************************************************************************/
/*!
\brief
Move ctor. Invalidates Vulkan handles.
\param rhs
the other command buffer.
*/
/***************************************************************************/
SHVkCommandBuffer::SHVkCommandBuffer(SHVkCommandBuffer&& rhs) noexcept
: vkCommandBuffer {std::move (rhs.vkCommandBuffer)}
, cmdBufferState {rhs.cmdBufferState}
, commandBufferType {rhs.commandBufferType}
, parentPoolResetMode {rhs.parentPoolResetMode}
, usageFlags {rhs.usageFlags}
, commandBufferCount {rhs.commandBufferCount}
, parentPool {rhs.parentPool}
, boundPipelineLayoutHdl{rhs.boundPipelineLayoutHdl }
: vkCommandBuffer{ std::move(rhs.vkCommandBuffer) }
, cmdBufferState{ rhs.cmdBufferState }
, commandBufferType{ rhs.commandBufferType }
, parentPoolResetMode{ rhs.parentPoolResetMode }
, usageFlags{ rhs.usageFlags }
, commandBufferCount{ rhs.commandBufferCount }
, parentPool{ rhs.parentPool }
, boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl }
{
memcpy (pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
rhs.vkCommandBuffer = VK_NULL_HANDLE;
}
/***************************************************************************/
/*!
\brief
Move assignment operator. Invalidates Vulkan handles.
\param rhs
The other Vulkan Handle.
\return
\return
a reference itself.
*/
/***************************************************************************/
SHVkCommandBuffer& SHVkCommandBuffer::operator=(SHVkCommandBuffer&& rhs) noexcept

View File

@ -203,7 +203,8 @@ namespace SHADE
}
// Transfer to GPU
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
if (transformDataBuffer[frameIndex])
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
}
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, uint32_t frameIndex)

View File

@ -150,9 +150,9 @@ namespace SHADE
//compositeSubpass->AddInput("Position");
// TODO: Use macro to add this node when SH_EDITOR is enabled
//auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {});
//auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
//imguiSubpass->AddColorOutput("Present");
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
worldRenderGraph->Generate();

View File

@ -348,7 +348,7 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
{
// Ensure updated transforms and materials are provided
// Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex);
// Draw all the batches
@ -524,6 +524,7 @@ namespace SHADE
, configured{ rhs.configured }
, executed{ rhs.executed }
, ptrToResources{ rhs.ptrToResources }
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
{
rhs.renderpass = {};
}
@ -544,6 +545,7 @@ namespace SHADE
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
subpassIndexing = std::move(rhs.subpassIndexing);
ptrToResources = std::move(rhs.ptrToResources);
pipelineLibrary = std::move(rhs.pipelineLibrary);
rhs.renderpass = {};
@ -625,7 +627,7 @@ namespace SHADE
}
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex)
{
{
batcher.FinaliseBatches(logicalDeviceHdl, frameIndex);
}
@ -993,6 +995,34 @@ namespace SHADE
}
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
: logicalDeviceHdl{ rhs.logicalDeviceHdl }
, swapchainHdl{ rhs.swapchainHdl }
, nodeIndexing{ std::move(rhs.nodeIndexing) }
, nodes{ std::move(rhs.nodes) }
, graphResources{ std::move(rhs.graphResources) }
, resourceManager{ std::move(rhs.resourceManager) }
, globalData{ rhs.globalData }
{
}
SHRenderGraph& SHRenderGraph::operator=(SHRenderGraph&& rhs) noexcept
{
if (&rhs == this)
return *this;
logicalDeviceHdl = rhs.logicalDeviceHdl;
swapchainHdl = rhs.swapchainHdl;
nodeIndexing = std::move(rhs.nodeIndexing);
nodes = std::move(rhs.nodes);
graphResources = std::move(rhs.graphResources);
resourceManager = std::move(rhs.resourceManager);
globalData = rhs.globalData;
return *this;
}
/***************************************************************************/
/*!
@ -1084,7 +1114,7 @@ namespace SHADE
}
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex)
{
{
for (auto& node : nodes)
{
node->FinaliseBatch(frameIndex);

View File

@ -279,6 +279,8 @@ namespace SHADE
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraph (void) noexcept;
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */