Provisional light culling
This commit is contained in:
@@ -16,21 +16,19 @@ struct PendingBuffer
|
||||
|
||||
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
||||
: graphics(graphics)
|
||||
, currentBuffer(0)
|
||||
, size(size)
|
||||
, currentOwner(queueType)
|
||||
, owner(queueType)
|
||||
{
|
||||
if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ||
|
||||
usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ||
|
||||
usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
|
||||
{
|
||||
numBuffers = 1;
|
||||
}
|
||||
else
|
||||
if(bDynamic)
|
||||
{
|
||||
numBuffers = Gfx::numFramesBuffered;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBuffers = 1;
|
||||
}
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
@@ -63,7 +61,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u
|
||||
|
||||
ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
auto cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
auto &deletionQueue = graphics->getDeletionQueue();
|
||||
VkDevice device = graphics->getDevice();
|
||||
VkBuffer buf[Gfx::numFramesBuffered];
|
||||
@@ -85,25 +83,25 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
VkBufferMemoryBarrier barrier =
|
||||
init::BufferMemoryBarrier();
|
||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
|
||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
|
||||
PCommandBufferManager dstManager = nullptr;
|
||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
|
||||
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
|
||||
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::COMPUTE)
|
||||
else if (owner == Gfx::QueueType::COMPUTE)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::GRAPHICS)
|
||||
else if (owner == Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
barrier.srcAccessMask = getSourceAccessMask();
|
||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
@@ -135,17 +133,36 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
||||
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||
for (uint32_t i = 0; i < numBuffers; ++i)
|
||||
barrier.offset = 0;
|
||||
barrier.size = size;
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
dynamicBarriers[i] = barrier;
|
||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||
dynamicBarriers[i].offset = 0;
|
||||
dynamicBarriers[i].size = size;
|
||||
}
|
||||
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
sourceManager->submitCommands();
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstAccessMask = dstAccess;
|
||||
barrier.srcAccessMask = srcAccess;
|
||||
barrier.offset = 0;
|
||||
barrier.size = size;
|
||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||
for(uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
dynamicBarriers[i] = barrier;
|
||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||
}
|
||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
}
|
||||
|
||||
void *ShaderBuffer::lock(bool bWriteOnly)
|
||||
@@ -168,7 +185,7 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
||||
|
||||
PendingBuffer pending;
|
||||
pending.bWriteOnly = bWriteOnly;
|
||||
pending.prevQueue = currentOwner;
|
||||
pending.prevQueue = owner;
|
||||
if (bWriteOnly)
|
||||
{
|
||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
@@ -178,12 +195,12 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
||||
}
|
||||
else
|
||||
{
|
||||
PCmdBuffer current = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||
graphics->getQueueCommands(currentOwner)->waitForCommands(current);
|
||||
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
current->waitForCommand();
|
||||
|
||||
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
VkCommandBuffer handle = graphics->getQueueCommands(currentOwner)->getCommands()->getHandle();
|
||||
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
|
||||
|
||||
VkBufferMemoryBarrier barrier =
|
||||
init::BufferMemoryBarrier();
|
||||
@@ -205,8 +222,8 @@ void *ShaderBuffer::lock(bool bWriteOnly)
|
||||
|
||||
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
||||
|
||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||
vkQueueWaitIdle(graphics->getQueueCommands(currentOwner)->getQueue()->getHandle());
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
||||
|
||||
stagingBuffer->flushMappedMemory();
|
||||
pending.stagingBuffer = stagingBuffer;
|
||||
@@ -230,14 +247,14 @@ void ShaderBuffer::unlock()
|
||||
if (pending.bWriteOnly)
|
||||
{
|
||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||
|
||||
VkBufferCopy region;
|
||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||
region.size = size;
|
||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
}
|
||||
//requestOwnershipTransfer(pending.prevQueue);
|
||||
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
||||
@@ -246,7 +263,7 @@ void ShaderBuffer::unlock()
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
|
||||
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
|
||||
, dedicatedStagingBuffer(nullptr)
|
||||
{
|
||||
if(createInfo.bDynamic)
|
||||
@@ -291,14 +308,14 @@ void UniformBuffer::unlock()
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
dedicatedStagingBuffer->flushMappedMemory();
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(ShaderBuffer::currentOwner)->getCommands();
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||
|
||||
VkBufferCopy region;
|
||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||
region.size = ShaderBuffer::size;
|
||||
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||
graphics->getQueueCommands(ShaderBuffer::currentOwner)->submitCommands();
|
||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -309,7 +326,6 @@ void UniformBuffer::unlock()
|
||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
{
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
Vulkan::ShaderBuffer::currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
@@ -317,6 +333,12 @@ void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
@@ -327,14 +349,14 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
|
||||
return VK_ACCESS_UNIFORM_READ_BIT;
|
||||
}
|
||||
|
||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
|
||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
|
||||
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
@@ -353,6 +375,12 @@ void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
@@ -365,7 +393,7 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
|
||||
{
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
@@ -389,6 +417,12 @@ void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
@@ -401,7 +435,7 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
|
||||
{
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
@@ -425,6 +459,12 @@ void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
|
||||
@@ -84,20 +84,38 @@ void CmdBuffer::endRenderPass()
|
||||
state = State::InsideBegin;
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(Array<Gfx::PRenderCommand> commands)
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
{
|
||||
assert(state == State::RenderPassActive);
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
auto command = commands[i].cast<SecondaryCmdBuffer>();
|
||||
auto command = commands[i].cast<RenderCommand>();
|
||||
// Cache array and size to save on pointer access
|
||||
for(auto boundDescriptor : command->boundDescriptors)
|
||||
{
|
||||
boundDescriptor->currentlyBound = this;
|
||||
}
|
||||
command->end();
|
||||
executingCommands.add(command);
|
||||
executingRenders.add(command);
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
}
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
{
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
auto command = commands[i].cast<ComputeCommand>();
|
||||
// Cache array and size to save on pointer access
|
||||
for(auto boundDescriptor : command->boundDescriptors)
|
||||
{
|
||||
boundDescriptor->currentlyBound = this;
|
||||
}
|
||||
command->end();
|
||||
executingComputes.add(command);
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
}
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
@@ -117,11 +135,16 @@ void CmdBuffer::refreshFence()
|
||||
{
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
fence->reset();
|
||||
for(auto command : executingCommands)
|
||||
for(auto command : executingComputes)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingCommands.clear();
|
||||
executingComputes.clear();
|
||||
for(auto command : executingRenders)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingRenders.clear();
|
||||
state = State::ReadyBegin;
|
||||
}
|
||||
}
|
||||
@@ -131,6 +154,13 @@ void CmdBuffer::refreshFence()
|
||||
}
|
||||
}
|
||||
|
||||
void CmdBuffer::waitForCommand(uint32 timeout)
|
||||
{
|
||||
fence->wait(timeout);
|
||||
refreshFence();
|
||||
}
|
||||
|
||||
|
||||
PFence CmdBuffer::getFence()
|
||||
{
|
||||
return fence;
|
||||
@@ -141,7 +171,7 @@ PCommandBufferManager CmdBuffer::getManager()
|
||||
return manager;
|
||||
}
|
||||
|
||||
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: CmdBufferBase(graphics, cmdPool)
|
||||
, ready(true)
|
||||
{
|
||||
@@ -152,27 +182,13 @@ SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
|
||||
}
|
||||
|
||||
SecondaryCmdBuffer::~SecondaryCmdBuffer()
|
||||
SecondaryCmdBuffer::~SecondaryCmdBuffer()
|
||||
{
|
||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||
}
|
||||
|
||||
void SecondaryCmdBuffer::begin(PCmdBuffer parent)
|
||||
{
|
||||
ready = false;
|
||||
VkCommandBufferBeginInfo beginInfo =
|
||||
init::CommandBufferBeginInfo();
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||
init::CommandBufferInheritanceInfo();
|
||||
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
|
||||
inheritanceInfo.renderPass = parent->renderPass->getHandle();
|
||||
inheritanceInfo.subpass = parent->subpassIndex;
|
||||
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
}
|
||||
|
||||
void SecondaryCmdBuffer::end()
|
||||
void SecondaryCmdBuffer::end()
|
||||
{
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
}
|
||||
@@ -188,12 +204,37 @@ void SecondaryCmdBuffer::reset()
|
||||
ready = true;
|
||||
}
|
||||
|
||||
bool SecondaryCmdBuffer::isReady()
|
||||
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: SecondaryCmdBuffer(graphics, cmdPool)
|
||||
{}
|
||||
|
||||
|
||||
RenderCommand::~RenderCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void RenderCommand::begin(PCmdBuffer parent)
|
||||
{
|
||||
ready = false;
|
||||
VkCommandBufferBeginInfo beginInfo =
|
||||
init::CommandBufferBeginInfo();
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||
init::CommandBufferInheritanceInfo();
|
||||
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
|
||||
inheritanceInfo.renderPass = parent->renderPass->getHandle();
|
||||
inheritanceInfo.subpass = parent->subpassIndex;
|
||||
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
}
|
||||
|
||||
|
||||
bool RenderCommand::isReady()
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
|
||||
void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
|
||||
void RenderCommand::setViewport(Gfx::PViewport viewport)
|
||||
{
|
||||
VkViewport vp = viewport.cast<Viewport>()->getHandle();
|
||||
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
|
||||
@@ -201,19 +242,19 @@ void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
|
||||
vkCmdSetScissor(handle, 0, 1, &scissors);
|
||||
}
|
||||
|
||||
void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
||||
{
|
||||
pipeline = gfxPipeline.cast<GraphicsPipeline>();
|
||||
pipeline->bind(handle);
|
||||
}
|
||||
void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||
{
|
||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||
boundDescriptors.add(descriptor.getHandle());
|
||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||
}
|
||||
void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
||||
{
|
||||
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||
@@ -225,7 +266,7 @@ void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descri
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
||||
delete[] sets;
|
||||
}
|
||||
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
||||
void RenderCommand::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
||||
{
|
||||
Array<VkBuffer> buffers(streams.size());
|
||||
Array<VkDeviceSize> offsets(streams.size());
|
||||
@@ -237,16 +278,76 @@ void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& stream
|
||||
};
|
||||
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
|
||||
}
|
||||
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||
{
|
||||
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
||||
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
||||
}
|
||||
void SecondaryCmdBuffer::draw(const MeshBatchElement& data)
|
||||
void RenderCommand::draw(const MeshBatchElement& data)
|
||||
{
|
||||
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: SecondaryCmdBuffer(graphics, cmdPool)
|
||||
{
|
||||
}
|
||||
|
||||
ComputeCommand::~ComputeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void ComputeCommand::begin(PCmdBuffer parent)
|
||||
{
|
||||
ready = false;
|
||||
VkCommandBufferBeginInfo beginInfo =
|
||||
init::CommandBufferBeginInfo();
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||
init::CommandBufferInheritanceInfo();
|
||||
inheritanceInfo.framebuffer = VK_NULL_HANDLE;
|
||||
inheritanceInfo.renderPass = VK_NULL_HANDLE;
|
||||
inheritanceInfo.subpass = 0;
|
||||
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
}
|
||||
|
||||
bool ComputeCommand::isReady()
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
|
||||
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
|
||||
{
|
||||
pipeline = computePipeline.cast<ComputePipeline>();
|
||||
pipeline->bind(handle);
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||
{
|
||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||
boundDescriptors.add(descriptor.getHandle());
|
||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
|
||||
{
|
||||
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||
{
|
||||
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||
boundDescriptors.add(descriptorSet.getHandle());
|
||||
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
|
||||
}
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
||||
delete[] sets;
|
||||
}
|
||||
|
||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
||||
{
|
||||
vkCmdDispatch(handle, threadX, threadY, threadZ);
|
||||
}
|
||||
|
||||
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
|
||||
{
|
||||
@@ -275,20 +376,40 @@ PCmdBuffer CommandBufferManager::getCommands()
|
||||
return activeCmdBuffer;
|
||||
}
|
||||
|
||||
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
|
||||
PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name)
|
||||
{
|
||||
std::scoped_lock lck(allocatedSecondBufferLock);
|
||||
for (uint32 i = 0; i < allocatedSecondBuffers.size(); ++i)
|
||||
std::scoped_lock lck(allocatedRenderLock);
|
||||
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
||||
{
|
||||
PSecondaryCmdBuffer cmdBuffer = allocatedSecondBuffers[i];
|
||||
if (cmdBuffer->isReady())
|
||||
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
|
||||
if (cmdBuffer->ready)
|
||||
{
|
||||
cmdBuffer->begin(activeCmdBuffer);
|
||||
return cmdBuffer;
|
||||
}
|
||||
}
|
||||
PSecondaryCmdBuffer result = new SecondaryCmdBuffer(graphics, commandPool);
|
||||
allocatedSecondBuffers.add(result);
|
||||
PRenderCommand result = new RenderCommand(graphics, commandPool);
|
||||
result->name = name;
|
||||
allocatedRenderCommands.add(result);
|
||||
result->begin(activeCmdBuffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
|
||||
{
|
||||
std::scoped_lock lck(allocatedComputeLock);
|
||||
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
||||
{
|
||||
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
|
||||
if (cmdBuffer->ready)
|
||||
{
|
||||
cmdBuffer->begin(activeCmdBuffer);
|
||||
return cmdBuffer;
|
||||
}
|
||||
}
|
||||
PComputeCommand result = new ComputeCommand(graphics, commandPool);
|
||||
result->name = name;
|
||||
allocatedComputeCommands.add(result);
|
||||
result->begin(activeCmdBuffer);
|
||||
return result;
|
||||
}
|
||||
@@ -332,9 +453,3 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
activeCmdBuffer->begin();
|
||||
}
|
||||
|
||||
void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
|
||||
{
|
||||
cmdBuffer->fence->wait(timeout);
|
||||
cmdBuffer->refreshFence();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ protected:
|
||||
};
|
||||
DEFINE_REF(CmdBufferBase)
|
||||
|
||||
DECLARE_REF(SecondaryCmdBuffer)
|
||||
DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(ComputeCommand)
|
||||
DECLARE_REF(CommandBufferManager)
|
||||
class CmdBuffer : public CmdBufferBase
|
||||
{
|
||||
@@ -40,9 +41,11 @@ public:
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void endRenderPass();
|
||||
void executeCommands(Array<Gfx::PRenderCommand> secondaryCommands);
|
||||
void executeCommands(const Array<Gfx::PRenderCommand>& secondaryCommands);
|
||||
void executeCommands(const Array<Gfx::PComputeCommand>& secondaryCommands);
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void refreshFence();
|
||||
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||
PFence getFence();
|
||||
PCommandBufferManager getManager();
|
||||
enum State
|
||||
@@ -63,23 +66,40 @@ private:
|
||||
State state;
|
||||
Array<PSemaphore> waitSemaphores;
|
||||
Array<VkPipelineStageFlags> waitFlags;
|
||||
Array<PSecondaryCmdBuffer> executingCommands;
|
||||
friend class SecondaryCmdBuffer;
|
||||
Array<PRenderCommand> executingRenders;
|
||||
Array<PComputeCommand> executingComputes;
|
||||
friend class RenderCommand;
|
||||
friend class CommandBufferManager;
|
||||
friend class Queue;
|
||||
};
|
||||
DEFINE_REF(CmdBuffer)
|
||||
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class SecondaryCmdBuffer : public Gfx::RenderCommand, public CmdBufferBase
|
||||
|
||||
class SecondaryCmdBuffer: public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~SecondaryCmdBuffer();
|
||||
void begin(PCmdBuffer parent);
|
||||
virtual void begin(PCmdBuffer parent) = 0;
|
||||
void end();
|
||||
void reset();
|
||||
bool ready;
|
||||
|
||||
protected:
|
||||
Array<DescriptorSet*> boundDescriptors;
|
||||
friend class CmdBuffer;
|
||||
};
|
||||
DEFINE_REF(SecondaryCmdBuffer);
|
||||
|
||||
class RenderCommand : public Gfx::RenderCommand, public SecondaryCmdBuffer
|
||||
{
|
||||
public:
|
||||
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~RenderCommand();
|
||||
virtual void begin(PCmdBuffer parent) override;
|
||||
virtual bool isReady() override;
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
@@ -91,12 +111,26 @@ public:
|
||||
|
||||
private:
|
||||
PGraphicsPipeline pipeline;
|
||||
Array<DescriptorSet*> boundDescriptors;
|
||||
bool ready;
|
||||
friend class CmdBuffer;
|
||||
};
|
||||
DEFINE_REF(SecondaryCmdBuffer)
|
||||
DEFINE_REF(RenderCommand)
|
||||
|
||||
class ComputeCommand : public Gfx::ComputeCommand, public SecondaryCmdBuffer
|
||||
{
|
||||
public:
|
||||
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~ComputeCommand();
|
||||
virtual void begin(PCmdBuffer parent) override;
|
||||
virtual bool isReady() override;
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
private:
|
||||
PComputePipeline pipeline;
|
||||
friend class CmdBuffer;
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
class CommandBufferManager
|
||||
{
|
||||
public:
|
||||
@@ -107,9 +141,9 @@ public:
|
||||
return queue;
|
||||
}
|
||||
PCmdBuffer getCommands();
|
||||
PSecondaryCmdBuffer createSecondaryCmdBuffer();
|
||||
PRenderCommand createRenderCommand(const std::string& name);
|
||||
PComputeCommand createComputeCommand(const std::string& name);
|
||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||
void waitForCommands(PCmdBuffer cmdBuffer, uint32 timeToWait = 1000000u);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
@@ -119,8 +153,10 @@ private:
|
||||
PCmdBuffer activeCmdBuffer;
|
||||
std::mutex allocatedBufferLock;
|
||||
Array<PCmdBuffer> allocatedBuffers;
|
||||
std::mutex allocatedSecondBufferLock;
|
||||
Array<PSecondaryCmdBuffer> allocatedSecondBuffers;
|
||||
std::mutex allocatedRenderLock;
|
||||
std::mutex allocatedComputeLock;
|
||||
Array<PRenderCommand> allocatedRenderCommands;
|
||||
Array<PComputeCommand> allocatedComputeCommands;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager)
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -117,7 +117,7 @@ DescriptorSet::~DescriptorSet()
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
|
||||
{
|
||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[Gfx::currentFrameIndex][binding]);
|
||||
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
|
||||
/*if(vulkanBuffer->isDataEquals(cachedBuffer))
|
||||
{
|
||||
std::cout << "uniform data equal, skip" << std::endl;
|
||||
@@ -125,32 +125,32 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
}*/
|
||||
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
||||
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
|
||||
cachedData[Gfx::currentFrameIndex][binding] = new UniformBuffer(*vulkanBuffer.getHandle());
|
||||
cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle());
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
|
||||
{
|
||||
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
|
||||
StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[Gfx::currentFrameIndex][binding]);
|
||||
StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[binding]);
|
||||
if(vulkanBuffer.getHandle() == cachedBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
|
||||
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
|
||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanBuffer.getHandle();
|
||||
cachedData[binding] = vulkanBuffer.getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
|
||||
{
|
||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[Gfx::currentFrameIndex][binding]);
|
||||
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[binding]);
|
||||
if(vulkanSampler.getHandle() == cachedSampler)
|
||||
{
|
||||
return;
|
||||
@@ -162,16 +162,16 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
imageInfos.add(imageInfo);
|
||||
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
|
||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanSampler.getHandle();
|
||||
cachedData[binding] = vulkanSampler.getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
|
||||
{
|
||||
TextureHandle* vulkanTexture = TextureBase::cast(texture);
|
||||
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[Gfx::currentFrameIndex][binding]);
|
||||
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[binding]);
|
||||
if(vulkanTexture == cachedTexture)
|
||||
{
|
||||
return;
|
||||
@@ -181,7 +181,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
init::DescriptorImageInfo(
|
||||
VK_NULL_HANDLE,
|
||||
vulkanTexture->getView(),
|
||||
vulkanTexture->getLayout());
|
||||
cast(vulkanTexture->getLayout()));
|
||||
if (samplerState != nullptr)
|
||||
{
|
||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||
@@ -190,7 +190,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
imageInfos.add(imageInfo);
|
||||
VkWriteDescriptorSet writeDescriptor =
|
||||
init::WriteDescriptorSet(
|
||||
setHandle[Gfx::currentFrameIndex],
|
||||
setHandle,
|
||||
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
binding,
|
||||
&imageInfos.back());
|
||||
@@ -200,7 +200,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
}
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
|
||||
cachedData[Gfx::currentFrameIndex][binding] = vulkanTexture;
|
||||
cachedData[binding] = vulkanTexture;
|
||||
}
|
||||
|
||||
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
||||
@@ -220,8 +220,8 @@ void DescriptorSet::writeChanges()
|
||||
{
|
||||
if(isCurrentlyBound())
|
||||
{
|
||||
graphics->getGraphicsCommands()->waitForCommands(currentlyBound);
|
||||
currentlyBound = nullptr;
|
||||
currentlyBound->waitForCommand(1000000000u);
|
||||
assert(!isCurrentlyBound());
|
||||
}
|
||||
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
||||
writeDescriptors.clear();
|
||||
@@ -258,7 +258,11 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
|
||||
poolSizes.add(size);
|
||||
}
|
||||
}
|
||||
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets * Gfx::numFramesBuffered);
|
||||
VkDescriptorPoolCreateInfo createInfo
|
||||
= init::DescriptorPoolCreateInfo(
|
||||
(uint32)poolSizes.size(),
|
||||
poolSizes.data(),
|
||||
maxSets * Gfx::numFramesBuffered);
|
||||
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
||||
}
|
||||
|
||||
@@ -271,14 +275,8 @@ DescriptorAllocator::~DescriptorAllocator()
|
||||
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
|
||||
{
|
||||
VkDescriptorSetLayout layoutHandle = layout.getHandle();
|
||||
VkDescriptorSetLayout layoutArray[Gfx::numFramesBuffered];
|
||||
for (uint32 i = 0; i < Gfx::numFramesBuffered; i++)
|
||||
{
|
||||
layoutArray[i] = layoutHandle;
|
||||
}
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo =
|
||||
init::DescriptorSetAllocateInfo(poolHandle, layoutArray, Gfx::numFramesBuffered);
|
||||
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
|
||||
|
||||
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
|
||||
{
|
||||
@@ -290,18 +288,17 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
|
||||
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
|
||||
{
|
||||
//If it hasnt been initialized, allocate it
|
||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, cachedHandles[setIndex]->setHandle));
|
||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
||||
|
||||
}
|
||||
cachedHandles[setIndex]->currentlyInUse = true;
|
||||
descriptorSet = cachedHandles[setIndex];
|
||||
|
||||
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
|
||||
for(uint32 frameIndex = 0; frameIndex < Gfx::numFramesBuffered; ++frameIndex)
|
||||
{
|
||||
vulkanSet->cachedData[frameIndex].resize(layout.bindings.size());
|
||||
// Not really pretty, but this way the set knows which ones are valid
|
||||
std::memset(vulkanSet->cachedData[frameIndex].data(), 0, sizeof(void*) * vulkanSet->cachedData[frameIndex].size());
|
||||
}
|
||||
vulkanSet->cachedData.resize(layout.bindings.size());
|
||||
// Not really pretty, but this way the set knows which ones are valid
|
||||
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
|
||||
|
||||
//Found set, stop searching
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,9 +60,12 @@ class DescriptorSet : public Gfx::DescriptorSet
|
||||
{
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
|
||||
: graphics(graphics), owner(owner), currentlyInUse(false), currentlyBound(nullptr)
|
||||
: setHandle(VK_NULL_HANDLE)
|
||||
, graphics(graphics)
|
||||
, owner(owner)
|
||||
, currentlyInUse(false)
|
||||
, currentlyBound(nullptr)
|
||||
{
|
||||
std::memset(setHandle, 0, sizeof(setHandle));
|
||||
}
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges();
|
||||
@@ -86,7 +89,7 @@ public:
|
||||
}
|
||||
inline VkDescriptorSet getHandle() const
|
||||
{
|
||||
return setHandle[Gfx::currentFrameIndex];
|
||||
return setHandle;
|
||||
}
|
||||
virtual uint32 getSetIndex() const;
|
||||
|
||||
@@ -97,8 +100,8 @@ private:
|
||||
// contains the previously bound resources at every binding
|
||||
// since the layout is fixed, trying to bind a texture to a buffer
|
||||
// would not work anyways, so casts should be safe
|
||||
Array<void*> cachedData[Gfx::numFramesBuffered];
|
||||
VkDescriptorSet setHandle[Gfx::numFramesBuffered];
|
||||
Array<void*> cachedData;
|
||||
VkDescriptorSet setHandle;
|
||||
PGraphics graphics;
|
||||
PDescriptorAllocator owner;
|
||||
PCmdBuffer currentlyBound;
|
||||
|
||||
@@ -81,13 +81,19 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
void Graphics::endRenderPass()
|
||||
{
|
||||
getGraphicsCommands()->getCommands()->endRenderPass();
|
||||
getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::PRenderCommand> commands)
|
||||
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
{
|
||||
getGraphicsCommands()->getCommands()->executeCommands(commands);
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
{
|
||||
getComputeCommands()->getCommands()->executeCommands(commands);
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
PTexture2D result = new Texture2D(this, createInfo);
|
||||
@@ -100,7 +106,7 @@ Gfx::PUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo
|
||||
return uniformBuffer;
|
||||
}
|
||||
|
||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
|
||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const StructuredBufferCreateInfo &bulkData)
|
||||
{
|
||||
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
|
||||
return structuredBuffer;
|
||||
@@ -116,9 +122,15 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
|
||||
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
|
||||
return indexBuffer;
|
||||
}
|
||||
Gfx::PRenderCommand Graphics::createRenderCommand()
|
||||
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||
{
|
||||
PSecondaryCmdBuffer cmdBuffer = getGraphicsCommands()->createSecondaryCmdBuffer();
|
||||
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name);
|
||||
return cmdBuffer;
|
||||
}
|
||||
|
||||
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||
{
|
||||
PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
|
||||
return cmdBuffer;
|
||||
}
|
||||
|
||||
@@ -158,6 +170,13 @@ Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& crea
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PComputeShader shader = new ComputeShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
|
||||
{
|
||||
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
@@ -189,6 +208,73 @@ Gfx::PPipelineLayout Graphics::createPipelineLayout()
|
||||
return layout;
|
||||
}
|
||||
|
||||
void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
|
||||
{
|
||||
Texture2D* src = (Texture2D*)srcTexture->getTexture2D();
|
||||
Texture2D* dst = (Texture2D*)dstTexture->getTexture2D();
|
||||
TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle();
|
||||
TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle();
|
||||
Gfx::SeImageLayout srcLayout = srcHandle->getLayout();
|
||||
Gfx::SeImageLayout dstLayout = dstHandle->getLayout();
|
||||
Gfx::QueueType dstOwner = dstHandle->currentOwner;
|
||||
src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
dstTexture->transferOwnership(srcHandle->currentOwner);
|
||||
PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands();
|
||||
if(srcHandle->getAspect() != dstHandle->getAspect())
|
||||
{
|
||||
/*VkMemoryRequirements imageRequirements;
|
||||
vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements);
|
||||
PStructuredBuffer tempBuffer = createStructuredBuffer();
|
||||
VkBufferImageCopy bufferImageCopy;
|
||||
bufferImageCopy.bufferOffset = 0;
|
||||
bufferImageCopy.bufferRowLength = srcTexture->getSizeX();
|
||||
bufferImageCopy.bufferImageHeight = srcTexture->getSizeY();
|
||||
bufferImageCopy.imageExtent.width = srcTexture->getSizeX();
|
||||
bufferImageCopy.imageExtent.height = srcTexture->getSizeY();
|
||||
bufferImageCopy.imageExtent.depth = 1;
|
||||
bufferImageCopy.imageOffset.x = 0;
|
||||
bufferImageCopy.imageOffset.y = 0;
|
||||
bufferImageCopy.imageOffset.z = 0;
|
||||
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
bufferImageCopy.imageSubresource.baseArrayLayer = 0;
|
||||
bufferImageCopy.imageSubresource.layerCount = 1;
|
||||
bufferImageCopy.imageSubresource.mipLevel = 0;
|
||||
|
||||
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy);
|
||||
|
||||
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy);
|
||||
delete tempBufferAllocation;*/
|
||||
throw new std::logic_error("Not yet implemented!");
|
||||
}
|
||||
else if (src->getSizeX() != dst->getSizeX()
|
||||
|| src->getSizeY() != dst->getSizeY())
|
||||
{
|
||||
throw new std::logic_error("Not yet implemented!");
|
||||
}
|
||||
else
|
||||
{
|
||||
VkImageCopy copy;
|
||||
std::memset(©, 0, sizeof(VkImageCopy));
|
||||
copy.extent.width = srcTexture->getSizeX();
|
||||
copy.extent.height = srcTexture->getSizeY();
|
||||
copy.extent.depth = 1;
|
||||
copy.srcSubresource.aspectMask = srcHandle->getAspect();
|
||||
copy.srcSubresource.layerCount = 1;
|
||||
copy.dstSubresource.aspectMask = dstHandle->getAspect();
|
||||
copy.dstSubresource.layerCount = 1;
|
||||
vkCmdCopyImage(cmdBuffer->getHandle(),
|
||||
srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©);
|
||||
src->changeLayout(srcLayout);
|
||||
dst->changeLayout(dstLayout);
|
||||
dstTexture->transferOwnership(dstOwner);
|
||||
}
|
||||
}
|
||||
|
||||
VkInstance Graphics::getInstance() const
|
||||
{
|
||||
return instance;
|
||||
|
||||
@@ -45,20 +45,23 @@ public:
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
|
||||
virtual void executeCommands(Array<Gfx::PRenderCommand> commands) override;
|
||||
virtual void executeCommands(const Array<Gfx::PRenderCommand>& commands) override;
|
||||
virtual void executeCommands(const Array<Gfx::PComputeCommand>& commands) override;
|
||||
|
||||
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PRenderCommand createRenderCommand() override;
|
||||
virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override;
|
||||
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
|
||||
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
|
||||
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||
@@ -66,6 +69,7 @@ public:
|
||||
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::PPipelineLayout createPipelineLayout() override;
|
||||
|
||||
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
||||
protected:
|
||||
Array<const char *> getRequiredExtensions();
|
||||
void initInstance(GraphicsInitializer initInfo);
|
||||
|
||||
@@ -1093,6 +1093,83 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
|
||||
return SE_FORMAT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
|
||||
{
|
||||
switch (imageLayout)
|
||||
{
|
||||
case SE_IMAGE_LAYOUT_UNDEFINED:
|
||||
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
case SE_IMAGE_LAYOUT_GENERAL:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_PREINITIALIZED:
|
||||
return VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
case SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
|
||||
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case SE_IMAGE_LAYOUT_PRESENT_SRC_KHR:
|
||||
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
case SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
|
||||
return VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
|
||||
case SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
|
||||
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||
default:
|
||||
return VK_IMAGE_LAYOUT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
|
||||
{
|
||||
switch (imageLayout)
|
||||
{
|
||||
case VK_IMAGE_LAYOUT_UNDEFINED:
|
||||
return SE_IMAGE_LAYOUT_UNDEFINED;
|
||||
case VK_IMAGE_LAYOUT_GENERAL:
|
||||
return SE_IMAGE_LAYOUT_GENERAL;
|
||||
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_PREINITIALIZED:
|
||||
return SE_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
|
||||
return SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
|
||||
return SE_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
|
||||
return SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
|
||||
case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
|
||||
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||
default:
|
||||
return SE_IMAGE_LAYOUT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
|
||||
{
|
||||
switch (storeOp)
|
||||
|
||||
@@ -34,6 +34,8 @@ VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
|
||||
VkFormat cast(const Gfx::SeFormat &format);
|
||||
Gfx::SeFormat cast(const VkFormat &format);
|
||||
VkImageLayout cast(const Gfx::SeImageLayout &imageLayout);
|
||||
Gfx::SeImageLayout cast(const VkImageLayout &imageLayout);
|
||||
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
||||
|
||||
@@ -49,7 +49,6 @@ void QueueOwnedResourceDeletion::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Semaphore::Semaphore(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include <functional>
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -88,7 +88,7 @@ private:
|
||||
class ShaderBuffer
|
||||
{
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
|
||||
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
|
||||
virtual ~ShaderBuffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
@@ -115,11 +115,14 @@ protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer;
|
||||
uint32 size;
|
||||
Gfx::QueueType currentOwner;
|
||||
Gfx::QueueType& owner;
|
||||
BufferAllocation buffers[Gfx::numFramesBuffered];
|
||||
uint32 numBuffers;
|
||||
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
|
||||
|
||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||
@@ -139,11 +142,14 @@ public:
|
||||
virtual void unlock() override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
|
||||
private:
|
||||
PStagingBuffer dedicatedStagingBuffer;
|
||||
};
|
||||
@@ -152,7 +158,7 @@ DEFINE_REF(UniformBuffer)
|
||||
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData);
|
||||
virtual ~StructuredBuffer();
|
||||
|
||||
protected:
|
||||
@@ -162,6 +168,10 @@ protected:
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
private:
|
||||
PStagingBuffer dedicatedStagingBuffer;
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer)
|
||||
|
||||
@@ -178,6 +188,8 @@ protected:
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
@@ -189,11 +201,13 @@ public:
|
||||
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
|
||||
@@ -201,14 +215,18 @@ class TextureHandle
|
||||
{
|
||||
public:
|
||||
TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureHandle();
|
||||
|
||||
inline VkImage getImage() const
|
||||
{
|
||||
return image;
|
||||
}
|
||||
inline VkImageView getView() const
|
||||
{
|
||||
return defaultView;
|
||||
}
|
||||
inline VkImageLayout getLayout() const
|
||||
inline Gfx::SeImageLayout getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
@@ -233,10 +251,13 @@ public:
|
||||
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
}
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
void changeLayout(VkImageLayout newLayout);
|
||||
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout);
|
||||
|
||||
Gfx::QueueType currentOwner;
|
||||
private:
|
||||
//Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
PSubAllocation allocation;
|
||||
uint32 sizeX;
|
||||
@@ -250,21 +271,22 @@ private:
|
||||
VkImage image;
|
||||
VkImageView defaultView;
|
||||
VkImageAspectFlags aspect;
|
||||
VkImageLayout layout;
|
||||
Gfx::SeImageLayout layout;
|
||||
friend class TextureBase;
|
||||
friend class Texture2D;
|
||||
friend class Graphics;
|
||||
};
|
||||
|
||||
class TextureBase
|
||||
{
|
||||
public:
|
||||
static TextureHandle* cast(Gfx::PTexture texture);
|
||||
void changeLayout(VkImageLayout newLayout);
|
||||
|
||||
protected:
|
||||
TextureHandle* textureHandle;
|
||||
friend class Graphics;
|
||||
};
|
||||
|
||||
DECLARE_REF(TextureBase)
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||
{
|
||||
public:
|
||||
@@ -286,6 +308,11 @@ public:
|
||||
{
|
||||
return textureHandle->getNumSamples();
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
|
||||
virtual void* getNativeHandle() override
|
||||
{
|
||||
return textureHandle;
|
||||
}
|
||||
inline VkImage getHandle() const
|
||||
{
|
||||
return textureHandle->image;
|
||||
@@ -301,6 +328,8 @@ public:
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
|
||||
@@ -120,6 +120,7 @@ void Shader::create(const ShaderCreateInfo& createInfo)
|
||||
char const* diagnostics = spGetDiagnosticOutput(request);
|
||||
std::cout << "Compile error for shader " << createInfo.name << std::endl;
|
||||
std::cout << diagnostics << std::endl;
|
||||
return;
|
||||
}
|
||||
size_t dataSize = 0;
|
||||
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
|
||||
|
||||
@@ -30,8 +30,8 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
|
||||
}
|
||||
|
||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||
: currentOwner(createInfo.resourceData.owner)
|
||||
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
|
||||
: currentOwner(owner)
|
||||
, graphics(graphics)
|
||||
, sizeX(createInfo.width)
|
||||
, sizeY(createInfo.height)
|
||||
@@ -43,7 +43,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
, usage(createInfo.usage)
|
||||
, image(existingImage)
|
||||
, aspect(getAspectFromFormat(createInfo.format))
|
||||
, layout(VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
, layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED)
|
||||
{
|
||||
if (existingImage == VK_NULL_HANDLE)
|
||||
{
|
||||
@@ -79,18 +79,18 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
break;
|
||||
}
|
||||
|
||||
info.initialLayout = layout;
|
||||
info.initialLayout = cast(layout);
|
||||
info.mipLevels = mipLevels;
|
||||
info.arrayLayers = arrayCount * layerCount;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.samples = (VkSampleCountFlagBits)samples;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = usage;
|
||||
//To upload to the image we need to specify transfer dst
|
||||
if(createInfo.resourceData.size > 0)
|
||||
{
|
||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
// Most of these flags will almost always be used
|
||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
|
||||
|
||||
VkMemoryDedicatedRequirements memDedicatedRequirements;
|
||||
@@ -112,7 +112,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
const BulkResourceData& resourceData = createInfo.resourceData;
|
||||
if(resourceData.size > 0)
|
||||
{
|
||||
changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
void* data = staging->getMappedPointer();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
@@ -136,11 +136,15 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
|
||||
changeLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
{
|
||||
changeLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
|
||||
VkImageViewCreateInfo viewInfo =
|
||||
@@ -176,17 +180,20 @@ TextureHandle* TextureBase::cast(Gfx::PTexture texture)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TextureHandle::changeLayout(VkImageLayout newLayout)
|
||||
void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout)
|
||||
{
|
||||
VkImageMemoryBarrier barrier =
|
||||
init::ImageMemoryBarrier(
|
||||
image,
|
||||
layout,
|
||||
newLayout);
|
||||
cast(layout),
|
||||
cast(newLayout));
|
||||
barrier.subresourceRange =
|
||||
init::ImageSubresourceRange(aspect);
|
||||
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
|
||||
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
cmdManager->submitCommands();
|
||||
layout = newLayout;
|
||||
}
|
||||
|
||||
@@ -195,8 +202,8 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
VkImageMemoryBarrier imageBarrier =
|
||||
init::ImageMemoryBarrier();
|
||||
imageBarrier.image = image;
|
||||
imageBarrier.oldLayout = layout;
|
||||
imageBarrier.newLayout = layout;
|
||||
imageBarrier.oldLayout = cast(layout);
|
||||
imageBarrier.newLayout = cast(layout);
|
||||
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
|
||||
PCommandBufferManager dstManager = nullptr;
|
||||
@@ -248,26 +255,49 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
|
||||
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||
currentOwner = newOwner;
|
||||
sourceManager->submitCommands();
|
||||
}
|
||||
|
||||
void TextureBase::changeLayout(VkImageLayout newLayout)
|
||||
void TextureHandle::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
textureHandle->changeLayout(newLayout);
|
||||
VkImageMemoryBarrier imageBarrier =
|
||||
init::ImageMemoryBarrier(
|
||||
image,
|
||||
cast(layout),
|
||||
cast(layout)
|
||||
);
|
||||
imageBarrier.srcAccessMask = srcAccess;
|
||||
imageBarrier.dstAccessMask = dstAccess;
|
||||
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
vkCmdPipelineBarrier(cmdBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
|
||||
{
|
||||
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
||||
createInfo, existingImage);
|
||||
createInfo, currentOwner, existingImage);
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
|
||||
{
|
||||
textureHandle->changeLayout(newLayout);
|
||||
}
|
||||
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
textureHandle->executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||
{
|
||||
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
@@ -162,7 +162,7 @@ void Window::advanceBackBuffer()
|
||||
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
||||
currentImageIndex = imageIndex;
|
||||
|
||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
@@ -193,7 +193,7 @@ void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
|
||||
|
||||
void Window::present()
|
||||
{
|
||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
|
||||
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
|
||||
VkPresentInfoKHR info;
|
||||
@@ -258,7 +258,6 @@ void Window::createSwapchain()
|
||||
Array<VkImage> swapchainImages(numSwapchainImages);
|
||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
|
||||
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
|
||||
TextureCreateInfo backBufferCreateInfo;
|
||||
backBufferCreateInfo.width = sizeX;
|
||||
@@ -274,10 +273,11 @@ void Window::createSwapchain()
|
||||
|
||||
VkClearColorValue clearColor;
|
||||
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
currentImageIndex = -1;
|
||||
|
||||
Reference in New Issue
Block a user