vulkan: skip TR & final pass on first frame before clearing buffers

This commit is contained in:
Flyinghead 2019-11-15 11:24:00 +01:00
parent 01af8e5f5e
commit a4053715af
2 changed files with 21 additions and 9 deletions

View File

@ -63,12 +63,14 @@ public:
const int zero = 0;
pixelCounterReset->upload(sizeof(zero), &zero);
}
// FIXME We need to wait until this buffer is not used before deleting it
// We need to wait until this buffer is not used before deleting it
VulkanContext::Instance()->GetGraphicsQueue().waitIdle();
abufferPointerAttachment.reset();
abufferPointerAttachment = std::unique_ptr<FramebufferAttachment>(
new FramebufferAttachment(context->GetPhysicalDevice(), context->GetDevice(), allocator));
abufferPointerAttachment->Init(width, height, vk::Format::eR32Uint, vk::ImageUsageFlagBits::eStorage);
abufferPointerTransitionNeeded = true;
firstFrameAfterInit = true;
if (!descSet)
descSet = std::move(context->GetDevice().allocateDescriptorSetsUnique(
@ -101,6 +103,10 @@ public:
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eFragmentShader, {}, nullptr, nullptr,
imageMemoryBarrier);
}
else
{
firstFrameAfterInit = false;
}
}
void ResetPixelCounter(vk::CommandBuffer commandBuffer)
@ -119,6 +125,7 @@ public:
void SetAllocator(Allocator *allocator) { this->allocator = allocator; }
vk::DescriptorSetLayout GetDescriptorSetLayout() const { return *descSetLayout; }
bool isFirstFrameAfterInit() const { return firstFrameAfterInit; }
private:
vk::UniqueDescriptorSet descSet;
@ -129,6 +136,7 @@ private:
std::unique_ptr<BufferData> pixelCounterReset;
std::unique_ptr<FramebufferAttachment> abufferPointerAttachment;
bool abufferPointerTransitionNeeded = false;
bool firstFrameAfterInit = false;
int maxWidth = 0;
int maxHeight = 0;
Allocator *allocator;

View File

@ -303,25 +303,29 @@ bool OITDrawer::Draw(const Texture *fogTexture)
DrawList(cmdBuffer, ListType_Punch_Through, false, 1, pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count);
// TR
DrawList(cmdBuffer, ListType_Translucent, current_pass.autosort, 3, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
if (!oitBuffers->isFirstFrameAfterInit())
DrawList(cmdBuffer, ListType_Translucent, current_pass.autosort, 3, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count);
// Final subpass
cmdBuffer.nextSubpass(vk::SubpassContents::eInline);
GetCurrentDescSet().BindColorInputDescSet(cmdBuffer, (pvrrc.render_passes.used() - 1 - render_pass) % 2);
// Tr modifier volumes
DrawModifierVolumes<true>(cmdBuffer, previous_pass.mvo_tr_count, current_pass.mvo_tr_count - previous_pass.mvo_tr_count);
if (!oitBuffers->isFirstFrameAfterInit())
{
// Tr modifier volumes
DrawModifierVolumes<true>(cmdBuffer, previous_pass.mvo_tr_count, current_pass.mvo_tr_count - previous_pass.mvo_tr_count);
vk::Pipeline pipeline = pipelineManager->GetFinalPipeline(current_pass.autosort);
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
quadBuffer->Bind(cmdBuffer);
quadBuffer->Draw(cmdBuffer);
vk::Pipeline pipeline = pipelineManager->GetFinalPipeline(current_pass.autosort);
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
quadBuffer->Bind(cmdBuffer);
quadBuffer->Draw(cmdBuffer);
}
// Clear
vk::MemoryBarrier memoryBarrier(vk::AccessFlagBits::eShaderRead, vk::AccessFlagBits::eShaderWrite);
cmdBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader, vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
pipeline = pipelineManager->GetClearPipeline();
vk::Pipeline pipeline = pipelineManager->GetClearPipeline();
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
quadBuffer->Draw(cmdBuffer);