mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- implement queue family transfers
This commit is contained in:
parent
651d749eea
commit
88355393df
6 changed files with 201 additions and 66 deletions
|
@ -347,7 +347,7 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
|
||||
PipelineBarrier barrier0;
|
||||
barrier0.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
barrier0.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
barrier0.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
void *data = Staging->Map(0, totalsize);
|
||||
memcpy(data, texture->Data.get(), totalsize);
|
||||
|
@ -359,18 +359,26 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
region.imageExtent.depth = 1;
|
||||
region.imageExtent.width = texture->Width;
|
||||
region.imageExtent.height = texture->Height;
|
||||
fb->GetUploadCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
PipelineBarrier barrier1;
|
||||
barrier1.addImage(Image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
barrier1.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
barrier1.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
Layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||
{
|
||||
PipelineBarrier transfer;
|
||||
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, Image.get(), Layout);
|
||||
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PipelineBarrier barrier;
|
||||
barrier.addImage(Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
||||
barrier.execute(fb->GetUploadCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
barrier.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
Layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,15 @@ void VKBuffer::SetData(size_t size, const void *data, bool staticdata)
|
|||
memcpy(dst, data, size);
|
||||
mStaging->Unmap();
|
||||
|
||||
fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get());
|
||||
fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get());
|
||||
|
||||
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||
{
|
||||
PipelineBarrier transfer;
|
||||
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, mBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
|
||||
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -78,7 +86,22 @@ void VKBuffer::SetSubData(size_t offset, size_t size, const void *data)
|
|||
memcpy(dst, data, size);
|
||||
mStaging->Unmap();
|
||||
|
||||
fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size);
|
||||
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||
{
|
||||
PipelineBarrier transfer;
|
||||
transfer.addQueueTransfer(fb->device->graphicsFamily, fb->device->transferFamily, mBuffer.get(), VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT, 0);
|
||||
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
|
||||
fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size);
|
||||
|
||||
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||
{
|
||||
PipelineBarrier transfer;
|
||||
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, mBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
|
||||
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -292,6 +292,8 @@ public:
|
|||
void addBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
||||
void addImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||
void addImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||
void addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
|
||||
void addQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1);
|
||||
|
||||
void execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags = 0);
|
||||
|
||||
|
@ -301,6 +303,24 @@ private:
|
|||
FixedSizeVector<VkImageMemoryBarrier, 8> imageMemoryBarriers;
|
||||
};
|
||||
|
||||
class QueueSubmit
|
||||
{
|
||||
public:
|
||||
QueueSubmit();
|
||||
|
||||
void addCommandBuffer(VulkanCommandBuffer *buffer);
|
||||
void addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore);
|
||||
void addSignal(VulkanSemaphore *semaphore);
|
||||
void execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence = nullptr);
|
||||
|
||||
private:
|
||||
VkSubmitInfo submitInfo = {};
|
||||
FixedSizeVector<VkSemaphore, 8> waitSemaphores;
|
||||
FixedSizeVector<VkPipelineStageFlags, 8> waitStages;
|
||||
FixedSizeVector<VkSemaphore, 8> signalSemaphores;
|
||||
FixedSizeVector<VkCommandBuffer, 8> commandBuffers;
|
||||
};
|
||||
|
||||
class WriteDescriptors
|
||||
{
|
||||
public:
|
||||
|
@ -1140,6 +1160,37 @@ inline void PipelineBarrier::addImage(VkImage image, VkImageLayout oldLayout, Vk
|
|||
imageMemoryBarriers.push_back(barrier);
|
||||
}
|
||||
|
||||
inline void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
|
||||
{
|
||||
VkBufferMemoryBarrier barrier = { };
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = srcAccessMask;
|
||||
barrier.dstAccessMask = dstAccessMask;
|
||||
barrier.srcQueueFamilyIndex = srcFamily;
|
||||
barrier.dstQueueFamilyIndex = dstFamily;
|
||||
barrier.buffer = buffer->buffer;
|
||||
barrier.offset = 0;
|
||||
barrier.size = buffer->size;
|
||||
bufferMemoryBarriers.push_back(barrier);
|
||||
}
|
||||
|
||||
inline void PipelineBarrier::addQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount)
|
||||
{
|
||||
VkImageMemoryBarrier barrier = { };
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.oldLayout = layout;
|
||||
barrier.newLayout = layout;
|
||||
barrier.srcQueueFamilyIndex = srcFamily;
|
||||
barrier.dstQueueFamilyIndex = dstFamily;
|
||||
barrier.image = image->image;
|
||||
barrier.subresourceRange.aspectMask = aspectMask;
|
||||
barrier.subresourceRange.baseMipLevel = baseMipLevel;
|
||||
barrier.subresourceRange.levelCount = levelCount;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
imageMemoryBarriers.push_back(barrier);
|
||||
}
|
||||
|
||||
inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags)
|
||||
{
|
||||
commandBuffer->pipelineBarrier(
|
||||
|
@ -1151,6 +1202,44 @@ inline void PipelineBarrier::execute(VulkanCommandBuffer *commandBuffer, VkPipel
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline QueueSubmit::QueueSubmit()
|
||||
{
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
}
|
||||
|
||||
inline void QueueSubmit::addCommandBuffer(VulkanCommandBuffer *buffer)
|
||||
{
|
||||
commandBuffers.push_back(buffer->buffer);
|
||||
submitInfo.pCommandBuffers = commandBuffers.data();
|
||||
submitInfo.commandBufferCount = (uint32_t)commandBuffers.size();
|
||||
}
|
||||
|
||||
inline void QueueSubmit::addWait(VkPipelineStageFlags waitStageMask, VulkanSemaphore *semaphore)
|
||||
{
|
||||
waitStages.push_back(waitStageMask);
|
||||
waitSemaphores.push_back(semaphore->semaphore);
|
||||
|
||||
submitInfo.pWaitDstStageMask = waitStages.data();
|
||||
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||
submitInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.size();
|
||||
}
|
||||
|
||||
inline void QueueSubmit::addSignal(VulkanSemaphore *semaphore)
|
||||
{
|
||||
signalSemaphores.push_back(semaphore->semaphore);
|
||||
submitInfo.pSignalSemaphores = signalSemaphores.data();
|
||||
submitInfo.signalSemaphoreCount = (uint32_t)signalSemaphores.size();
|
||||
}
|
||||
|
||||
inline void QueueSubmit::execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence)
|
||||
{
|
||||
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, fence ? fence->fence : VK_NULL_HANDLE);
|
||||
if (result < VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to submit command buffer");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void WriteDescriptors::addBuffer(VulkanDescriptorSet *descriptorSet, int binding, VkDescriptorType type, VulkanBuffer *buffer)
|
||||
{
|
||||
addBuffer(descriptorSet, binding, type, buffer, 0, buffer->size);
|
||||
|
|
|
@ -118,8 +118,10 @@ void VulkanFrameBuffer::InitializeState()
|
|||
uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment;
|
||||
maxuniformblock = device->PhysicalDevice.Properties.limits.maxUniformBufferRange;
|
||||
|
||||
mUploadSemaphore.reset(new VulkanSemaphore(device));
|
||||
mTransferSemaphore.reset(new VulkanSemaphore(device));
|
||||
mPreDrawSemaphore.reset(new VulkanSemaphore(device));
|
||||
mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily));
|
||||
mTransferCommandPool.reset(new VulkanCommandPool(device, device->transferFamily));
|
||||
|
||||
mScreenBuffers.reset(new VkRenderBuffers());
|
||||
mSaveBuffers.reset(new VkRenderBuffers());
|
||||
|
@ -206,7 +208,8 @@ void VulkanFrameBuffer::Update()
|
|||
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
||||
|
||||
mDrawCommands.reset();
|
||||
mUploadCommands.reset();
|
||||
mTransferCommands.reset();
|
||||
mPreDrawCommands.reset();
|
||||
DeleteFrameObjects();
|
||||
|
||||
Finish.Unclock();
|
||||
|
@ -224,62 +227,50 @@ void VulkanFrameBuffer::DeleteFrameObjects()
|
|||
|
||||
void VulkanFrameBuffer::SubmitCommands(bool finish)
|
||||
{
|
||||
if (mTransferCommands)
|
||||
{
|
||||
mTransferCommands->end();
|
||||
|
||||
QueueSubmit submit;
|
||||
submit.addCommandBuffer(mTransferCommands.get());
|
||||
submit.addSignal(mTransferSemaphore.get());
|
||||
submit.execute(device, device->transferQueue);
|
||||
}
|
||||
|
||||
if (mPreDrawCommands)
|
||||
{
|
||||
mPreDrawCommands->end();
|
||||
|
||||
QueueSubmit submit;
|
||||
submit.addCommandBuffer(mPreDrawCommands.get());
|
||||
if (mTransferCommands)
|
||||
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mTransferSemaphore.get());
|
||||
submit.addSignal(mPreDrawSemaphore.get());
|
||||
submit.execute(device, device->graphicsQueue);
|
||||
}
|
||||
|
||||
mDrawCommands->end();
|
||||
|
||||
if (mUploadCommands)
|
||||
QueueSubmit submit;
|
||||
submit.addCommandBuffer(mDrawCommands.get());
|
||||
if (mPreDrawCommands)
|
||||
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mPreDrawSemaphore.get());
|
||||
else if (mTransferCommands)
|
||||
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mTransferSemaphore.get());
|
||||
if (finish)
|
||||
{
|
||||
mUploadCommands->end();
|
||||
|
||||
// Submit upload commands immediately
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mUploadCommands->buffer;
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &mUploadSemaphore->semaphore;
|
||||
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
if (result < VK_SUCCESS)
|
||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
||||
|
||||
// Wait for upload commands to finish, then submit render commands
|
||||
VkSemaphore waitSemaphores[] = { mUploadSemaphore->semaphore, mSwapChainImageAvailableSemaphore->semaphore };
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
submitInfo.waitSemaphoreCount = finish ? 2 : 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mDrawCommands->buffer;
|
||||
submitInfo.signalSemaphoreCount = finish ? 1 : 0;
|
||||
submitInfo.pSignalSemaphores = &mRenderFinishedSemaphore->semaphore;
|
||||
result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, mRenderFinishedFence->fence);
|
||||
if (result < VK_SUCCESS)
|
||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
VkSemaphore waitSemaphores[] = { mSwapChainImageAvailableSemaphore->semaphore };
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.waitSemaphoreCount = finish ? 1 : 0;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mDrawCommands->buffer;
|
||||
submitInfo.signalSemaphoreCount = finish ? 1 : 0;
|
||||
submitInfo.pSignalSemaphores = &mRenderFinishedSemaphore->semaphore;
|
||||
VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, mRenderFinishedFence->fence);
|
||||
if (result < VK_SUCCESS)
|
||||
I_FatalError("Failed to submit command buffer! Error %d\n", result);
|
||||
submit.addWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get());
|
||||
submit.addSignal(mRenderFinishedSemaphore.get());
|
||||
}
|
||||
submit.execute(device, device->graphicsQueue, mRenderFinishedFence.get());
|
||||
|
||||
if (!finish)
|
||||
{
|
||||
vkWaitForFences(device->device, 1, &mRenderFinishedFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
vkResetFences(device->device, 1, &mRenderFinishedFence->fence);
|
||||
mDrawCommands.reset();
|
||||
mUploadCommands.reset();
|
||||
mTransferCommands.reset();
|
||||
mPreDrawCommands.reset();
|
||||
DeleteFrameObjects();
|
||||
}
|
||||
}
|
||||
|
@ -794,15 +785,26 @@ void VulkanFrameBuffer::Draw2D()
|
|||
::Draw2D(&m2DDrawer, *mRenderState);
|
||||
}
|
||||
|
||||
VulkanCommandBuffer *VulkanFrameBuffer::GetUploadCommands()
|
||||
VulkanCommandBuffer *VulkanFrameBuffer::GetTransferCommands()
|
||||
{
|
||||
if (!mUploadCommands)
|
||||
if (!mTransferCommands)
|
||||
{
|
||||
mUploadCommands = mGraphicsCommandPool->createBuffer();
|
||||
mUploadCommands->SetDebugName("VulkanFrameBuffer.mUploadCommands");
|
||||
mUploadCommands->begin();
|
||||
mTransferCommands = mTransferCommandPool->createBuffer();
|
||||
mTransferCommands->SetDebugName("VulkanFrameBuffer.mTransferCommands");
|
||||
mTransferCommands->begin();
|
||||
}
|
||||
return mUploadCommands.get();
|
||||
return mTransferCommands.get();
|
||||
}
|
||||
|
||||
VulkanCommandBuffer *VulkanFrameBuffer::GetPreDrawCommands()
|
||||
{
|
||||
if (!mPreDrawCommands)
|
||||
{
|
||||
mPreDrawCommands = mGraphicsCommandPool->createBuffer();
|
||||
mPreDrawCommands->SetDebugName("VulkanFrameBuffer.mPreDrawCommands");
|
||||
mPreDrawCommands->begin();
|
||||
}
|
||||
return mPreDrawCommands.get();
|
||||
}
|
||||
|
||||
VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands()
|
||||
|
|
|
@ -25,7 +25,8 @@ public:
|
|||
std::unique_ptr<VulkanSwapChain> swapChain;
|
||||
uint32_t presentImageIndex = 0;
|
||||
|
||||
VulkanCommandBuffer *GetUploadCommands();
|
||||
VulkanCommandBuffer *GetTransferCommands();
|
||||
VulkanCommandBuffer *GetPreDrawCommands();
|
||||
VulkanCommandBuffer *GetDrawCommands();
|
||||
VkShaderManager *GetShaderManager() { return mShaderManager.get(); }
|
||||
VkSamplerManager *GetSamplerManager() { return mSamplerManager.get(); }
|
||||
|
@ -114,9 +115,12 @@ private:
|
|||
std::unique_ptr<VkPostprocess> mPostprocess;
|
||||
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
|
||||
std::unique_ptr<VulkanCommandPool> mGraphicsCommandPool;
|
||||
std::unique_ptr<VulkanCommandBuffer> mUploadCommands;
|
||||
std::unique_ptr<VulkanCommandPool> mTransferCommandPool;
|
||||
std::unique_ptr<VulkanCommandBuffer> mTransferCommands;
|
||||
std::unique_ptr<VulkanCommandBuffer> mPreDrawCommands;
|
||||
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
||||
std::unique_ptr<VulkanSemaphore> mUploadSemaphore;
|
||||
std::unique_ptr<VulkanSemaphore> mTransferSemaphore;
|
||||
std::unique_ptr<VulkanSemaphore> mPreDrawSemaphore;
|
||||
std::unique_ptr<VkRenderState> mRenderState;
|
||||
|
||||
std::unique_ptr<VulkanSemaphore> mSwapChainImageAvailableSemaphore;
|
||||
|
|
|
@ -195,7 +195,7 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
|||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetUploadCommands();
|
||||
auto cmdbuffer = fb->GetPreDrawCommands();
|
||||
|
||||
PipelineBarrier imageTransition;
|
||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||
|
@ -231,7 +231,7 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
|
|||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetUploadCommands();
|
||||
auto cmdbuffer = fb->GetTransferCommands();
|
||||
|
||||
PipelineBarrier imageTransition0;
|
||||
imageTransition0.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
|
@ -289,6 +289,15 @@ void VkHardwareTexture::GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer
|
|||
PipelineBarrier barrier2;
|
||||
barrier2.addImage(image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, i - 1);
|
||||
barrier2.execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
auto fb = GetVulkanFrameBuffer();
|
||||
if (fb->device->transferFamily != fb->device->graphicsFamily)
|
||||
{
|
||||
PipelineBarrier transfer;
|
||||
transfer.addQueueTransfer(fb->device->transferFamily, fb->device->graphicsFamily, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, 0, GetMipLevels(image->width, image->height));
|
||||
transfer.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
transfer.execute(fb->GetPreDrawCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
int VkHardwareTexture::GetMipLevels(int w, int h)
|
||||
|
@ -326,7 +335,7 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
|
|||
mImageView = viewbuilder.create(fb->device);
|
||||
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||
|
||||
auto cmdbuffer = fb->GetUploadCommands();
|
||||
auto cmdbuffer = fb->GetPreDrawCommands();
|
||||
|
||||
PipelineBarrier imageTransition;
|
||||
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, mImageLayout, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||
|
|
Loading…
Reference in a new issue