Merge pull request #12931 from unknownbrackets/vulkan-postshader

Vulkan: Create FB compatible pipelines in Draw
This commit is contained in:
Henrik Rydgård 2020-05-19 09:03:41 +02:00 committed by GitHub
commit 886fff0990
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 40 deletions

View File

@ -352,6 +352,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vector<Draw::ShaderModul
void PresentationCommon::CreateDeviceObjects() {
using namespace Draw;
assert(vdata_ == nullptr);
vdata_ = draw_->CreateBuffer(sizeof(Vertex) * 8, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);

View File

@ -78,7 +78,7 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk
vulkan_(vulkan) {
presentation_->SetLanguage(GLSL_VULKAN);
DeviceRestore(vulkan, draw);
InitDeviceObjects();
// After a blit we do need to rebind for the VulkanRenderManager to know what to do.
needGLESRebinds_ = true;
@ -410,17 +410,6 @@ void FramebufferManagerVulkan::DeviceLost() {
DestroyAllFBOs();
DestroyDeviceObjects();
presentation_->DeviceLost();
if (allocator_) {
allocator_->Destroy();
// We have to delete on queue, so this can free its queued deletions.
vulkan_->Delete().QueueCallback([](void *ptr) {
auto allocator = static_cast<VulkanDeviceAllocator *>(ptr);
delete allocator;
}, allocator_);
allocator_ = nullptr;
}
}
void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) {
@ -428,9 +417,5 @@ void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawCo
draw_ = draw;
presentation_->DeviceRestore(draw);
_assert_(!allocator_);
allocator_ = new VulkanDeviceAllocator(vulkan_, 1 * 1024 * 1024, 8 * 1024 * 1024);
InitDeviceObjects();
}

View File

@ -84,7 +84,6 @@ private:
TextureCacheVulkan *textureCacheVulkan_ = nullptr;
ShaderManagerVulkan *shaderManagerVulkan_ = nullptr;
DrawEngineVulkan *drawEngineVulkan_ = nullptr;
VulkanDeviceAllocator *allocator_ = nullptr;
VulkanPushBuffer *push_;
enum {

View File

@ -251,7 +251,8 @@ public:
ubo_ = new uint8_t[uboSize_];
}
~VKPipeline() {
vulkan_->Delete().QueueDeletePipeline(vkpipeline);
vulkan_->Delete().QueueDeletePipeline(backbufferPipeline);
vulkan_->Delete().QueueDeletePipeline(framebufferPipeline);
delete[] ubo_;
}
@ -272,7 +273,8 @@ public:
return false;
}
VkPipeline vkpipeline;
VkPipeline backbufferPipeline = VK_NULL_HANDLE;
VkPipeline framebufferPipeline = VK_NULL_HANDLE;
int stride[4]{};
int dynamicUniformSize = 0;
@ -420,6 +422,7 @@ public:
void DrawIndexed(int vertexCount, int offset) override;
void DrawUP(const void *vdata, int vertexCount) override;
void BindCompatiblePipeline();
void ApplyDynamicState();
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
@ -1024,30 +1027,40 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
raster->ToVulkan(&rs);
VkGraphicsPipelineCreateInfo info{ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
info.flags = 0;
info.stageCount = (uint32_t)stages.size();
info.pStages = stages.data();
info.pColorBlendState = &blend->info;
info.pDepthStencilState = &depth->info;
info.pDynamicState = &dynamicInfo;
info.pInputAssemblyState = &inputAssembly;
info.pTessellationState = nullptr;
info.pMultisampleState = &ms;
info.pVertexInputState = &input->visc;
info.pRasterizationState = &rs;
info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically.
info.layout = pipelineLayout_;
info.subpass = 0;
info.renderPass = renderManager_.GetBackbufferRenderPass();
VkGraphicsPipelineCreateInfo createInfo[2];
for (auto &info : createInfo) {
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
info.flags = 0;
info.stageCount = (uint32_t)stages.size();
info.pStages = stages.data();
info.pColorBlendState = &blend->info;
info.pDepthStencilState = &depth->info;
info.pDynamicState = &dynamicInfo;
info.pInputAssemblyState = &inputAssembly;
info.pTessellationState = nullptr;
info.pMultisampleState = &ms;
info.pVertexInputState = &input->visc;
info.pRasterizationState = &rs;
info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically.
info.layout = pipelineLayout_;
info.subpass = 0;
}
// OK, need to create a new pipeline.
VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 1, &info, nullptr, &pipeline->vkpipeline);
createInfo[0].renderPass = renderManager_.GetBackbufferRenderPass();
createInfo[1].renderPass = renderManager_.GetFramebufferRenderPass();
// OK, need to create new pipelines.
VkPipeline pipelines[2]{};
VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 2, createInfo, nullptr, pipelines);
if (result != VK_SUCCESS) {
ELOG("Failed to create graphics pipeline");
delete pipeline;
return nullptr;
}
pipeline->backbufferPipeline = pipelines[0];
pipeline->framebufferPipeline = pipelines[1];
if (desc.uniformDesc) {
pipeline->dynamicUniformSize = (int)desc.uniformDesc->uniformBufferSize;
}
@ -1249,7 +1262,7 @@ void VKContext::Draw(int vertexCount, int offset) {
VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf);
renderManager_.BindPipeline(curPipeline_->vkpipeline);
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset);
}
@ -1265,7 +1278,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) {
VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf);
renderManager_.BindPipeline(curPipeline_->vkpipeline);
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
}
@ -1277,11 +1290,20 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) {
VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf);
renderManager_.BindPipeline(curPipeline_->vkpipeline);
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount);
}
void VKContext::BindCompatiblePipeline() {
VkRenderPass renderPass = renderManager_.GetCompatibleRenderPass();
if (renderPass == renderManager_.GetBackbufferRenderPass()) {
renderManager_.BindPipeline(curPipeline_->backbufferPipeline);
} else {
renderManager_.BindPipeline(curPipeline_->framebufferPipeline);
}
}
void VKContext::Clear(int clearMask, uint32_t colorval, float depthVal, int stencilVal) {
int mask = 0;
if (clearMask & FBChannel::FB_COLOR_BIT)