Merge remote-tracking branch 'origin/SP3-1-Rendering' into SP3-1-Rendering
This commit is contained in:
commit
1290e99dda
|
@ -8,6 +8,7 @@
|
|||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/Images/SHVkImage.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
|
||||
|
||||
|
@ -421,9 +422,42 @@ namespace SHADE
|
|||
vkCommandBuffer.drawIndexed(indexCount, 1, firstIndex, vertexOffset, 0);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Issues a multi indirect draw call.
|
||||
|
||||
void SHVkCommandBuffer::PipelineBarrier (
|
||||
\param indirectDrawData
|
||||
SHVkBuffer containing the data for the multi indirect draw call.
|
||||
\param drawCount
|
||||
Number of multi indirect draw sub-calls stored in indirectDrawData.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
|
||||
void SHVkCommandBuffer::DrawMultiIndirect(Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount)
|
||||
{
|
||||
if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING)
|
||||
{
|
||||
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound.");
|
||||
return;
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
|
||||
void SHVkCommandBuffer::PipelineBarrier(
|
||||
vk::PipelineStageFlags srcStage,
|
||||
vk::PipelineStageFlags dstStage,
|
||||
vk::DependencyFlags deps,
|
||||
|
@ -457,33 +491,6 @@ namespace SHADE
|
|||
// //vkCommandBuffer.pipelineBarrier()
|
||||
//}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Issues a multi indirect draw call.
|
||||
|
||||
\param indirectDrawData
|
||||
SHVkBuffer containing the data for the multi indirect draw call.
|
||||
\param drawCount
|
||||
Number of multi indirect draw sub-calls stored in indirectDrawData.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
|
||||
void SHVkCommandBuffer::DrawMultiIndirect(Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount)
|
||||
{
|
||||
if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING)
|
||||
{
|
||||
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound.");
|
||||
return;
|
||||
}
|
||||
|
||||
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace SHADE
|
|||
class SHVkFramebuffer;
|
||||
class SHVkPipeline;
|
||||
class SHVkBuffer;
|
||||
class SHVkImage;
|
||||
class SHVkDescriptorSetGroup;
|
||||
|
||||
enum class SH_CMD_BUFFER_TYPE
|
||||
|
@ -116,6 +117,10 @@ namespace SHADE
|
|||
// Draw Commands
|
||||
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
||||
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
||||
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
||||
|
||||
// Buffer Copy
|
||||
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
||||
|
||||
// memory barriers
|
||||
void PipelineBarrier (
|
||||
|
@ -129,7 +134,6 @@ namespace SHADE
|
|||
|
||||
bool IsReadyToSubmit (void) const noexcept;
|
||||
void HandlePostSubmit (void) noexcept;
|
||||
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
||||
|
||||
// Push Constant variable setting
|
||||
template <typename T>
|
||||
|
|
|
@ -234,7 +234,7 @@ namespace SHADE
|
|||
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
||||
}
|
||||
|
||||
void SHVkImage::TransferToDeviceResource(void) noexcept
|
||||
void SHVkImage::TransferToDeviceResource(Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept
|
||||
{
|
||||
// prepare copy regions
|
||||
std::vector<vk::BufferImageCopy> copyRegions{mipOffsets.size()};
|
||||
|
@ -252,7 +252,7 @@ namespace SHADE
|
|||
copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
|
||||
}
|
||||
|
||||
//PrepareImageTransition();
|
||||
cmdBufferHdl->CopyBufferToImage(stagingBuffer, vkImage, copyRegions);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -274,7 +274,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
|
||||
void SHVkImage::PrepareImageTransitionInfo(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
|
||||
{
|
||||
barrier.oldLayout = oldLayout;
|
||||
barrier.newLayout = newLayout;
|
||||
|
@ -286,33 +286,6 @@ namespace SHADE
|
|||
barrier.subresourceRange.levelCount = mipLevelCount;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = layerCount;
|
||||
|
||||
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
|
||||
if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
|
||||
{
|
||||
srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
dstStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
}
|
||||
else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
|
||||
{
|
||||
srcStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
|
||||
// TODO, what if we want to access in compute shader
|
||||
dstStage = vk::PipelineStageFlagBits::eFragmentShader;
|
||||
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("Image layouts are invalid. ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
||||
|
|
|
@ -135,8 +135,8 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||
void TransferToDeviceResource (void) noexcept;
|
||||
void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* GETTERS AND SETTERS */
|
||||
|
|
|
@ -13,29 +13,130 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "SHpch.h"
|
||||
#include "SHTextureLibrary.h"
|
||||
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHTexture> SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData)
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHTexture> SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels)
|
||||
{
|
||||
return {};
|
||||
isDirty = true;
|
||||
|
||||
auto handle = resourceManager.Create<SHTexture>();
|
||||
addJobs.emplace_back(AddJob { pixelCount, pixelData, format, mipLevels });
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SHTextureLibrary::Remove(Handle<SHTexture> mesh)
|
||||
void SHTextureLibrary::Remove(Handle<SHTexture> texture)
|
||||
{
|
||||
if (!texture)
|
||||
throw std::invalid_argument("Attempted to remove a Texture that did not belong to the Texture Library!");
|
||||
|
||||
removeJobs.emplace_back(texture);
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
void SHTextureLibrary::BuildBuffers(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer)
|
||||
void SHTextureLibrary::BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> descLayout)
|
||||
{
|
||||
/* Remove Textures */
|
||||
std::vector<vk::ImageMemoryBarrier> pipelineBarriers(addJobs.size());
|
||||
|
||||
/* Add Textures */
|
||||
// Transition
|
||||
for (int i = 0; auto& job : addJobs)
|
||||
{
|
||||
job.Image = resourceManager.Create<SHVkImage>();
|
||||
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]);
|
||||
++i;
|
||||
}
|
||||
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers);
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
||||
|
||||
// Copy
|
||||
for (auto& job : addJobs)
|
||||
{
|
||||
job.Image->TransferToDeviceResource(cmdBuffer);
|
||||
}
|
||||
|
||||
// Transition
|
||||
for (int i = 0; auto & job : addJobs)
|
||||
{
|
||||
// Transition
|
||||
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]);
|
||||
}
|
||||
preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers);
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
||||
|
||||
// Execute Commands
|
||||
graphicsQueue->SubmitCommandBuffer({ cmdBuffer });
|
||||
device->WaitIdle();
|
||||
|
||||
// Create Image View
|
||||
for (auto& job : addJobs)
|
||||
{
|
||||
const SHImageViewDetails DETAILS
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = job.TextureFormat,
|
||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = job.MipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 0
|
||||
};
|
||||
job.Handle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
||||
}
|
||||
|
||||
// Build Descriptor
|
||||
Handle<SHVkDescriptorSetGroup> descSetGroup = descPool->Allocate({ descLayout }, { 1 }).front();
|
||||
|
||||
|
||||
isDirty = false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHTextureLibrary::preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers)
|
||||
{
|
||||
if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
|
||||
{
|
||||
srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
dstStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
|
||||
for (auto& barrier : barriers)
|
||||
{
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
}
|
||||
}
|
||||
else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
|
||||
{
|
||||
srcStage = vk::PipelineStageFlagBits::eTransfer;
|
||||
|
||||
// TODO, what if we want to access in compute shader
|
||||
dstStage = vk::PipelineStageFlagBits::eFragmentShader;
|
||||
|
||||
for (auto& barrier : barriers)
|
||||
{
|
||||
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("Image layouts are invalid. ");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,11 +37,15 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
using PixelChannel = uint8_t;
|
||||
using PixelChannel = void;
|
||||
using TextureFormat = vk::Format; // TODO: Change
|
||||
using Index = uint32_t;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkImageView> ImageView;
|
||||
Index TextureArrayIndex = std::numeric_limits<Index>::max();
|
||||
};
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
|
@ -61,7 +65,7 @@ namespace SHADE
|
|||
|
||||
\brief
|
||||
Adds a texture to the Texture Library. But this does not mean that the
|
||||
textures have been added yet. A call to "BuildBuffers()" is required to
|
||||
textures have been added yet. A call to "BuildImages()" is required to
|
||||
transfer all textures into the GPU.
|
||||
|
||||
\param pixelCount
|
||||
|
@ -69,20 +73,22 @@ namespace SHADE
|
|||
\param positions
|
||||
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||
positions.
|
||||
\param format
|
||||
Format of the texture loaded in.
|
||||
|
||||
\return
|
||||
Handle to the created Texture. This is not valid to be used until a call to
|
||||
BuildBuffers().
|
||||
BuildImages().
|
||||
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData);
|
||||
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels);
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Removes a mesh from the Texture Library. But this does not mean that the
|
||||
textures have been removed yet. A call to "BuildBuffers()" is required to
|
||||
textures have been removed yet. A call to "BuildImages()" is required to
|
||||
finalise all changes.
|
||||
|
||||
\param mesh
|
||||
|
@ -106,7 +112,7 @@ namespace SHADE
|
|||
queue.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void BuildBuffers(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer);
|
||||
void BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
|
@ -119,10 +125,14 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
struct AddJob
|
||||
{
|
||||
uint32_t PixelCount = 0;
|
||||
const SHTexture::PixelChannel* PixelData = nullptr;
|
||||
Handle<SHTexture> Handle;
|
||||
uint32_t PixelCount = 0;
|
||||
const SHTexture::PixelChannel* PixelData = nullptr;
|
||||
SHTexture::TextureFormat TextureFormat = {};
|
||||
int MipLevels = 0;
|
||||
Handle<SHVkImage> Image;
|
||||
Handle<SHTexture> Handle;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -130,7 +140,7 @@ namespace SHADE
|
|||
std::vector<AddJob> addJobs;
|
||||
std::vector<Handle<SHTexture>> removeJobs;
|
||||
// Tracking
|
||||
ResourceLibrary<SHTexture> textures{};
|
||||
ResourceManager resourceManager;
|
||||
std::vector<Handle<SHTexture>> texOrder;
|
||||
// CPU Storage
|
||||
std::vector<SHTexture::PixelChannel> texStorage;
|
||||
|
@ -138,5 +148,10 @@ namespace SHADE
|
|||
Handle<SHVkBuffer> texStorageBuffer{};
|
||||
// Flags
|
||||
bool isDirty = true;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue