vulkan: VMU display

Reset pipeline when switching per-triangle/per-strip
Adreno workaround test typo
clean up
This commit is contained in:
Flyinghead 2019-12-25 13:09:54 +01:00
parent be50fca2d6
commit d49373b0f9
15 changed files with 304 additions and 86 deletions

View File

@ -71,6 +71,11 @@ static void display_vmus();
static void reset_vmus();
static void term_vmus();
float gui_get_scaling()
{
return scaling;
}
void gui_init()
{
if (inited)
@ -237,9 +242,9 @@ void ImGui_Impl_NewFrame()
}
static double last_render;
std::vector<float> render_times;
std::vector<float> render_times(100);
void gui_dosmth(int width, int height)
void gui_rendertick()
{
if (last_render == 0)
{
@ -251,15 +256,11 @@ void gui_dosmth(int width, int height)
if (render_times.size() > 100)
render_times.erase(render_times.begin());
last_render = new_time;
}
ImGui_Impl_NewFrame();
ImGui::NewFrame();
void gui_plot_render_time(int width, int height)
{
ImGui::PlotLines("Render Times", &render_times[0], render_times.size(), 0, "", 0.0, 1.0 / 30.0, ImVec2(300, 50));
// Render dear imgui into screen
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData());
}
// Helper to display a little (?) mark which shows a tooltip when hovered.
@ -1665,6 +1666,7 @@ void gui_display_osd()
}
if (settings.rend.FloatVMUs)
display_vmus();
// gui_plot_render_time(screen_width, screen_height);
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData());
@ -1713,8 +1715,9 @@ void gui_refresh_files()
#define VMU_WIDTH (70 * 48 * scaling / 32)
#define VMU_HEIGHT (70 * scaling)
#define VMU_PADDING (8 * scaling)
static u32 vmu_lcd_data[8][48 * 32];
static bool vmu_lcd_status[8];
u32 vmu_lcd_data[8][48 * 32];
bool vmu_lcd_status[8];
bool vmu_lcd_changed[8];
static ImTextureID vmu_lcd_tex_ids[8];
void push_vmu_screen(int bus_id, int bus_port, u8* buffer)
@ -1726,6 +1729,7 @@ void push_vmu_screen(int bus_id, int bus_port, u8* buffer)
for (int i = 0; i < ARRAY_SIZE(vmu_lcd_data[vmu_id]); i++, buffer++)
*p++ = *buffer != 0 ? 0xFFFFFFFFu : 0xFF000000u;
vmu_lcd_status[vmu_id] = true;
vmu_lcd_changed[vmu_id] = true;
}
static const int vmu_coords[8][2] = {
@ -1743,7 +1747,6 @@ static void display_vmus()
{
if (!game_started)
return;
// TODO Vulkan
if (!settings.pvr.IsOpenGL())
return;
ImGui::SetNextWindowBgAlpha(0);
@ -1794,7 +1797,6 @@ static void reset_vmus()
static void term_vmus()
{
// TODO Vulkan
if (!settings.pvr.IsOpenGL())
return;
for (int i = 0; i < ARRAY_SIZE(vmu_lcd_status); i++)

View File

@ -17,6 +17,7 @@
along with reicast. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "types.h"
void gui_init();
void gui_open_settings();
@ -28,6 +29,9 @@ void gui_term();
void gui_refresh_files();
extern int screen_dpi;
extern u32 vmu_lcd_data[8][48 * 32];
extern bool vmu_lcd_status[8];
extern bool vmu_lcd_changed[8];
typedef enum { Closed, Commands, Settings, ClosedNoResume, Main, Onboarding, VJoyEdit, VJoyEditCommands } GuiState;
extern GuiState gui_state;
@ -41,3 +45,4 @@ static inline bool gui_is_content_browser()
{
return gui_state == Main;
}
float gui_get_scaling();

View File

@ -23,6 +23,7 @@
#include "vulkan/imgui_impl_vulkan.h"
#include "gles/imgui_impl_opengl3.h"
#include "vulkan/vulkan_context.h"
#include "gui.h"
typedef void (*StringCallback)(bool cancelled, std::string selection);
@ -35,16 +36,19 @@ static inline void ImGui_impl_RenderDrawData(ImDrawData *draw_data, bool save_ba
{
VulkanContext *context = VulkanContext::Instance();
bool rendering = context->IsRendering();
const std::vector<vk::UniqueCommandBuffer> *vmuCmdBuffers = nullptr;
if (!rendering)
{
context->NewFrame();
vmuCmdBuffers = context->PrepareVMUs();
context->BeginRenderPass();
context->PresentLastFrame();
context->DrawVMUs(gui_get_scaling());
}
// Record Imgui Draw Data and draw funcs into command buffer
ImGui_ImplVulkan_RenderDrawData(draw_data, (VkCommandBuffer)context->GetCurrentCommandBuffer());
if (!rendering)
context->EndFrame();
context->EndFrame(vmuCmdBuffers);
}
else
#endif

View File

@ -108,6 +108,11 @@ protected:
void NewImage()
{
imageIndex = (imageIndex + 1) % GetContext()->GetSwapChainSize();
if (perStripSorting != settings.rend.PerStripSorting)
{
perStripSorting = settings.rend.PerStripSorting;
pipelineManager->Reset();
}
}
void Init(SamplerManager *samplerManager, PipelineManager *pipelineManager)
@ -174,6 +179,7 @@ private:
std::vector<std::vector<SortTrigDrawParam>> sortedPolys;
std::vector<std::vector<u32>> sortedIndexes;
u32 sortedIndexCount = 0;
bool perStripSorting = false;
};
class ScreenDrawer : public Drawer

View File

@ -347,7 +347,7 @@ bool OITDrawer::Draw(const Texture *fogTexture)
if (!oitBuffers->isFirstFrameAfterInit())
{
// Tr modifier volumes
if (!GetContext()->GetVendorID() != VENDOR_QUALCOMM) // Adreno bug
if (GetContext()->GetVendorID() != VENDOR_QUALCOMM) // Adreno bug
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);

View File

@ -45,7 +45,6 @@ public:
screenDrawer.Init(&samplerManager, &shaderManager, &oitBuffers);
screenDrawer.SetCommandPool(&texCommandPool);
quadBuffer = std::unique_ptr<QuadBuffer>(new QuadBuffer());
#ifdef __ANDROID__
if (!vjoyTexture)
@ -107,7 +106,6 @@ public:
textureDrawer.Term();
oitBuffers.Term();
osdBuffer.reset();
quadBuffer = nullptr;
textureCache.Clear();
fogTexture = nullptr;
texCommandPool.Term();
@ -295,7 +293,6 @@ private:
}
OITBuffers oitBuffers;
std::unique_ptr<QuadBuffer> quadBuffer;
std::unique_ptr<Texture> fogTexture;
CommandPool texCommandPool;

View File

@ -155,8 +155,7 @@ public:
if (this->renderPass != renderPass)
{
this->renderPass = renderPass;
pipelines.clear();
modVolPipelines.clear();
Reset();
}
}
@ -182,6 +181,13 @@ public:
return *modVolPipelines[pipehash];
}
void Reset()
{
pipelines.clear();
modVolPipelines.clear();
}
vk::PipelineLayout GetPipelineLayout() const { return *pipelineLayout; }
vk::DescriptorSetLayout GetPerFrameDSLayout() const { return *perFrameLayout; }
vk::DescriptorSetLayout GetPerPolyDSLayout() const { return *perPolyLayout; }

View File

@ -128,9 +128,9 @@ void QuadPipeline::Init(ShaderManager *shaderManager, vk::RenderPass renderPass)
pipelineLayout = GetContext()->GetDevice().createPipelineLayoutUnique(
vk::PipelineLayoutCreateInfo(vk::PipelineLayoutCreateFlags(), 1, &descSetLayout.get()));
}
if (!sampler)
if (!linearSampler)
{
sampler = GetContext()->GetDevice().createSamplerUnique(
linearSampler = GetContext()->GetDevice().createSamplerUnique(
vk::SamplerCreateInfo(vk::SamplerCreateFlags(),
vk::Filter::eLinear, vk::Filter::eLinear,
vk::SamplerMipmapMode::eLinear,
@ -140,35 +140,50 @@ void QuadPipeline::Init(ShaderManager *shaderManager, vk::RenderPass renderPass)
16.0f, false, vk::CompareOp::eNever, 0.0f, 0.0f,
vk::BorderColor::eFloatOpaqueBlack));
}
if (!nearestSampler)
{
nearestSampler = GetContext()->GetDevice().createSamplerUnique(
vk::SamplerCreateInfo(vk::SamplerCreateFlags(),
vk::Filter::eNearest, vk::Filter::eNearest,
vk::SamplerMipmapMode::eNearest,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToBorder,
vk::SamplerAddressMode::eClampToBorder, 0.0f, false,
16.0f, false, vk::CompareOp::eNever, 0.0f, 0.0f,
vk::BorderColor::eFloatOpaqueBlack));
}
if (this->renderPass != renderPass)
{
this->renderPass = renderPass;
pipeline.reset();
}
descriptorSets.resize(GetContext()->GetSwapChainSize());
}
void QuadPipeline::SetTexture(vk::ImageView imageView)
void QuadDrawer::Init(QuadPipeline *pipeline)
{
vk::UniqueDescriptorSet &descriptorSet = descriptorSets[GetContext()->GetCurrentImageIndex()];
if (!descriptorSet)
this->pipeline = pipeline;
buffer = std::unique_ptr<QuadBuffer>(new QuadBuffer());
descriptorSets.resize(VulkanContext::Instance()->GetSwapChainSize());
}
void QuadDrawer::Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[], bool nearestFilter)
{
VulkanContext *context = GetContext();
auto &descSet = descriptorSets[context->GetCurrentImageIndex()];
if (!descSet)
{
descriptorSet = std::move(
GetContext()->GetDevice().allocateDescriptorSetsUnique(
vk::DescriptorSetAllocateInfo(
GetContext()->GetDescriptorPool(), 1,
&descSetLayout.get())).front());
vk::DescriptorSetLayout layout = pipeline->GetDescSetLayout();
descSet = std::move(context->GetDevice().allocateDescriptorSetsUnique(
vk::DescriptorSetAllocateInfo(context->GetDescriptorPool(), 1, &layout)).front());
}
vk::DescriptorImageInfo imageInfo(*sampler, imageView, vk::ImageLayout::eShaderReadOnlyOptimal);
vk::DescriptorImageInfo imageInfo(nearestFilter ? pipeline->GetNearestSampler() : pipeline->GetLinearSampler(), imageView, vk::ImageLayout::eShaderReadOnlyOptimal);
std::vector<vk::WriteDescriptorSet> writeDescriptorSets;
writeDescriptorSets.push_back(
vk::WriteDescriptorSet(*descriptorSet, 0, 0, 1, vk::DescriptorType::eCombinedImageSampler, &imageInfo,
nullptr, nullptr));
GetContext()->GetDevice().updateDescriptorSets(writeDescriptorSets, nullptr);
}
vk::WriteDescriptorSet(*descSet, 0, 0, 1, vk::DescriptorType::eCombinedImageSampler, &imageInfo, nullptr, nullptr));
context->GetDevice().updateDescriptorSets(writeDescriptorSets, nullptr);
commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline->GetPipelineLayout(), 0, 1, &descSet.get(), 0, nullptr);
void QuadPipeline::BindDescriptorSets(vk::CommandBuffer cmdBuffer)
{
cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, *pipelineLayout, 0, 1,
&descriptorSets[GetContext()->GetCurrentImageIndex()].get(), 0, nullptr);
buffer->Update(vertices);
buffer->Bind(commandBuffer);
buffer->Draw(commandBuffer);
}

View File

@ -54,10 +54,10 @@ public:
if (vertices == nullptr)
{
static QuadVertex defaultVtx[] = {
{ { -1, -1, 0 }, { 0, 0 } },
{ { 1, -1, 0 }, { 1, 0 } },
{ { -1, 1, 0 }, { 0, 1 } },
{ { 1, 1, 0 }, { 1, 1 } },
{ { -1.f, -1.f, 0.f }, { 0.f, 0.f } },
{ { 1.f, -1.f, 0.f }, { 1.f, 0.f } },
{ { -1.f, 1.f, 0.f }, { 0.f, 1.f } },
{ { 1.f, 1.f, 0.f }, { 1.f, 1.f } },
};
vertices = defaultVtx;
};
@ -73,29 +73,42 @@ public:
void Init(ShaderManager *shaderManager, vk::RenderPass renderPass);
void Term() {
pipeline.reset();
sampler.reset();
descriptorSets.clear();
linearSampler.reset();
nearestSampler.reset();
pipelineLayout.reset();
descSetLayout.reset();
}
void BindPipeline(vk::CommandBuffer commandBuffer) { commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, GetPipeline()); }
vk::DescriptorSetLayout GetDescSetLayout() const { return *descSetLayout; }
vk::PipelineLayout GetPipelineLayout() const { return *pipelineLayout; }
vk::Sampler GetLinearSampler() const { return *linearSampler; }
vk::Sampler GetNearestSampler() const { return *nearestSampler; }
private:
vk::Pipeline GetPipeline()
{
if (!pipeline)
CreatePipeline();
return *pipeline;
}
void SetTexture(vk::ImageView imageView);
void BindDescriptorSets(vk::CommandBuffer cmdBuffer);
private:
void CreatePipeline();
vk::RenderPass renderPass;
vk::UniquePipeline pipeline;
vk::UniqueSampler sampler;
std::vector<vk::UniqueDescriptorSet> descriptorSets;
vk::UniqueSampler linearSampler;
vk::UniqueSampler nearestSampler;
vk::UniquePipelineLayout pipelineLayout;
vk::UniqueDescriptorSetLayout descSetLayout;
ShaderManager *shaderManager;
};
class QuadDrawer
{
public:
void Init(QuadPipeline *pipeline);
void Draw(vk::CommandBuffer commandBuffer, vk::ImageView imageView, QuadVertex vertices[] = nullptr, bool nearestFilter = false);
private:
QuadPipeline *pipeline = nullptr;
std::unique_ptr<QuadBuffer> buffer;
std::vector<vk::UniqueDescriptorSet> descriptorSets;
};

View File

@ -30,11 +30,6 @@ void setImageLayout(vk::CommandBuffer const& commandBuffer, vk::Image image, vk:
struct Texture : BaseTextureCacheData
{
~Texture() override
{
imageView.reset();
image.reset();
}
void UploadToGPU(int width, int height, u8 *data) override;
u64 GetIntId() { return (u64)reinterpret_cast<uintptr_t>(this); }
std::string GetId() override { char s[20]; sprintf(s, "%p", this); return s; }
@ -61,14 +56,13 @@ private:
std::unique_ptr<BufferData> stagingBufferData;
vk::CommandBuffer commandBuffer;
vk::UniqueDeviceMemory deviceMemory;
vk::UniqueImageView imageView;
Allocation allocation;
vk::UniqueImage image;
vk::UniqueImageView imageView;
vk::ImageView readOnlyImageView;
vk::PhysicalDevice physicalDevice;
vk::Device device;
Allocation allocation;
friend class TextureDrawer;
friend class OITTextureDrawer;
@ -125,13 +119,13 @@ private:
vk::Extent2D extent;
std::unique_ptr<BufferData> stagingBufferData;
Allocation allocation;
vk::UniqueImage image;
vk::UniqueImageView imageView;
vk::UniqueImageView stencilView;
vk::UniqueImage image;
vk::PhysicalDevice physicalDevice;
vk::Device device;
Allocation allocation;
};
class TextureCache : public BaseTextureCache<Texture>

111
core/rend/vulkan/vmu.cpp Normal file
View File

@ -0,0 +1,111 @@
/*
Created on: Dec 13, 2019
Copyright 2019 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "vmu.h"
#include "texture.h"
#include "rend/gui.h"
VulkanVMUs::~VulkanVMUs()
{
}
const std::vector<vk::UniqueCommandBuffer>* VulkanVMUs::PrepareVMUs(vk::CommandPool commandPool)
{
VulkanContext *context = VulkanContext::Instance();
commandBuffers.resize(context->GetSwapChainSize());
commandBuffers[context->GetCurrentImageIndex()].clear();
for (int i = 0; i < 8; i++)
{
std::unique_ptr<Texture>& texture = vmuTextures[i];
if (!vmu_lcd_status[i])
{
texture.reset();
continue;
}
bool update = vmu_lcd_changed[i];
if (!texture)
{
texture = std::unique_ptr<Texture>(new Texture());
update = true;
}
if (!update)
continue;
texture->tex_type = TextureType::_8888;
texture->SetDevice(context->GetDevice());
texture->SetPhysicalDevice(context->GetPhysicalDevice());
commandBuffers[context->GetCurrentImageIndex()].emplace_back(std::move(
VulkanContext::Instance()->GetDevice().allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo(commandPool, vk::CommandBufferLevel::ePrimary, 1))
.front()));
texture->SetCommandBuffer(*commandBuffers[context->GetCurrentImageIndex()].back());
texture->UploadToGPU(48, 32, (u8*)vmu_lcd_data[i]);
texture->SetCommandBuffer(nullptr);
vmu_lcd_changed[i] = false;
}
return &commandBuffers[context->GetCurrentImageIndex()];
}
void VulkanVMUs::DrawVMUs(vk::Extent2D viewport, float scaling)
{
f32 vmu_padding = 8.f * scaling;
f32 vmu_height = 70.f * scaling;
f32 vmu_width = 48.f / 32.f * vmu_height;
VulkanContext *context = VulkanContext::Instance();
vk::CommandBuffer commandBuffer = context->GetCurrentCommandBuffer();
pipeline->BindPipeline(commandBuffer);
float blendConstants[4] = { 0.75f, 0.75f, 0.75f, 0.75f };
commandBuffer.setBlendConstants(blendConstants);
QuadVertex vtx[] = {
{ { -1.f, -1.f, 0.f }, { 0.f, 1.f } },
{ { 1.f, -1.f, 0.f }, { 1.f, 1.f } },
{ { -1.f, 1.f, 0.f }, { 0.f, 0.f } },
{ { 1.f, 1.f, 0.f }, { 1.f, 0.f } },
};
for (int i = 0; i < 8; i++)
{
if (!vmuTextures[i])
continue;
f32 x;
if (i & 2)
x = viewport.width - vmu_padding - vmu_width;
else
x = vmu_padding;
f32 y;
if (i & 4)
{
y = viewport.height - vmu_padding - vmu_height;
if (i & 1)
y -= vmu_padding + vmu_height;
}
else
{
y = vmu_padding;
if (i & 1)
y += vmu_padding + vmu_height;
}
vk::Viewport viewport(x, y, vmu_width, vmu_height);
commandBuffer.setViewport(0, 1, &viewport);
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(x, y), vk::Extent2D(vmu_width, vmu_height)));
drawers[i]->Draw(commandBuffer, vmuTextures[i]->GetImageView(), vtx, true);
}
}

48
core/rend/vulkan/vmu.h Normal file
View File

@ -0,0 +1,48 @@
/*
Created on: Dec 13, 2019
Copyright 2019 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <memory>
#include "quad.h"
class Texture;
class VulkanVMUs
{
public:
~VulkanVMUs();
void Init(QuadPipeline *pipeline) {
this->pipeline = pipeline;
for (auto& drawer : drawers)
{
drawer = std::unique_ptr<QuadDrawer>(new QuadDrawer());
drawer->Init(pipeline);
}
}
const std::vector<vk::UniqueCommandBuffer>* PrepareVMUs(vk::CommandPool commandPool);
void DrawVMUs(vk::Extent2D viewport, float scaling);
private:
std::array<std::unique_ptr<Texture>, 8> vmuTextures;
std::vector<std::vector<vk::UniqueCommandBuffer>> commandBuffers;
std::array<std::unique_ptr<QuadDrawer>, 8> drawers;
QuadPipeline *pipeline = nullptr;
};

View File

@ -29,6 +29,7 @@
#endif
#include "compiler.h"
#include "utils.h"
#include "texture.h"
VulkanContext *VulkanContext::contextInstance;
@ -479,9 +480,9 @@ bool VulkanContext::InitDevice()
}
allocator.Init(physicalDevice, *device);
quadBuffer = std::unique_ptr<QuadBuffer>(new QuadBuffer());
shaderManager = std::unique_ptr<ShaderManager>(new ShaderManager());
quadPipeline = std::unique_ptr<QuadPipeline>(new QuadPipeline());
quadDrawer = std::unique_ptr<QuadDrawer>(new QuadDrawer());
CreateSwapChain();
@ -648,6 +649,8 @@ void VulkanContext::CreateSwapChain()
imageAcquiredSemaphores.push_back(device->createSemaphoreUnique(vk::SemaphoreCreateInfo()));
}
quadPipeline->Init(shaderManager.get(), *renderPass);
quadDrawer->Init(quadPipeline.get());
vmus->Init(quadPipeline.get());
InitImgui();
@ -702,6 +705,7 @@ bool VulkanContext::Init()
vk::AndroidSurfaceCreateInfoKHR createInfo(vk::AndroidSurfaceCreateFlagsKHR(), (struct ANativeWindow*)window);
surface = instance->createAndroidSurfaceKHRUnique(createInfo);
#endif
vmus = std::unique_ptr<VulkanVMUs>(new VulkanVMUs());
return InitDevice();
}
@ -731,13 +735,18 @@ void VulkanContext::BeginRenderPass()
vk::SubpassContents::eInline);
}
void VulkanContext::EndFrame()
void VulkanContext::EndFrame(const std::vector<vk::UniqueCommandBuffer> *cmdBuffers)
{
vk::CommandBuffer commandBuffer = *commandBuffers[currentImage];
commandBuffer.endRenderPass();
commandBuffer.end();
vk::PipelineStageFlags wait_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
vk::SubmitInfo submitInfo(1, &(*imageAcquiredSemaphores[currentSemaphore]), &wait_stage, 1, &commandBuffer, 1, &(*renderCompleteSemaphores[currentSemaphore]));
std::vector<vk::CommandBuffer> allCmdBuffers;
if (cmdBuffers != nullptr)
allCmdBuffers = vk::uniqueToRaw(*cmdBuffers);
allCmdBuffers.push_back(commandBuffer);
vk::SubmitInfo submitInfo(1, &(*imageAcquiredSemaphores[currentSemaphore]), &wait_stage, allCmdBuffers.size(),allCmdBuffers.data(),
1, &(*renderCompleteSemaphores[currentSemaphore]));
graphicsQueue.submit(1, &submitInfo, *drawFences[currentImage]);
verify(rendering);
rendering = false;
@ -769,14 +778,9 @@ void VulkanContext::DrawFrame(vk::ImageView imageView, vk::Offset2D extent)
{ { -1, 1, 0 }, { 0 - marginWidth, 1 } },
{ { 1, 1, 0 }, { 1 + marginWidth, 1 } },
};
quadBuffer->Update(vtx);
vk::CommandBuffer commandBuffer = GetCurrentCommandBuffer();
vk::Pipeline pipeline = quadPipeline->GetPipeline();
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
quadPipeline->SetTexture(imageView);
quadPipeline->BindDescriptorSets(commandBuffer);
quadPipeline->BindPipeline(commandBuffer);
float blendConstants[4] = { 1.0, 1.0, 1.0, 1.0 };
commandBuffer.setBlendConstants(blendConstants);
@ -784,8 +788,17 @@ void VulkanContext::DrawFrame(vk::ImageView imageView, vk::Offset2D extent)
vk::Viewport viewport(0, 0, width, height);
commandBuffer.setViewport(0, 1, &viewport);
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), vk::Extent2D(width, height)));
quadBuffer->Bind(commandBuffer);
quadBuffer->Draw(commandBuffer);
quadDrawer->Draw(commandBuffer, imageView, vtx);
}
const std::vector<vk::UniqueCommandBuffer> *VulkanContext::PrepareVMUs()
{
return vmus->PrepareVMUs(*commandPools[GetCurrentImageIndex()]);
}
void VulkanContext::DrawVMUs(float scaling)
{
vmus->DrawVMUs(vk::Extent2D(width, height), scaling);
}
extern Renderer *renderer;
@ -793,11 +806,17 @@ extern Renderer *renderer;
void VulkanContext::PresentFrame(vk::ImageView imageView, vk::Offset2D extent)
{
NewFrame();
const std::vector<vk::UniqueCommandBuffer> *vmuCmdBuffers = nullptr;
if (settings.rend.FloatVMUs)
vmuCmdBuffers = PrepareVMUs();
BeginRenderPass();
DrawFrame(imageView, extent);
if (settings.rend.FloatVMUs)
DrawVMUs(gui_get_scaling());
renderer->DrawOSD(false);
EndFrame();
EndFrame(vmuCmdBuffers);
lastFrameView = imageView;
lastFrameExtent = extent;
@ -828,12 +847,13 @@ void VulkanContext::Term()
}
}
}
vmus.reset();
ShaderCompiler::Term();
swapChain.reset();
imageViews.clear();
framebuffers.clear();
renderPass.reset();
quadBuffer.reset();
quadDrawer.reset();
quadPipeline.reset();
shaderManager.reset();
descriptorPool.reset();

View File

@ -23,6 +23,7 @@
#include "vmallocator.h"
#include "quad.h"
#include "rend/TexCache.h"
#include "vmu.h"
extern int screen_width, screen_height;
@ -50,7 +51,7 @@ public:
void SetWindowSize(u32 width, u32 height) { this->width = screen_width = width; this->height = screen_height = height; }
void NewFrame();
void BeginRenderPass();
void EndFrame();
void EndFrame(const std::vector<vk::UniqueCommandBuffer> *cmdBuffers = nullptr);
void Present();
void PresentFrame(vk::ImageView imageView, vk::Offset2D extent);
void PresentLastFrame();
@ -103,6 +104,8 @@ public:
u32 GetMaxStorageBufferRange() const { return maxStorageBufferRange; }
vk::DeviceSize GetMaxMemoryAllocationSize() const { return maxMemoryAllocationSize; }
u32 GetVendorID() const { return vendorID; }
const std::vector<vk::UniqueCommandBuffer> *PrepareVMUs();
void DrawVMUs(float scaling);
private:
vk::Format FindDepthFormat();
@ -198,13 +201,15 @@ private:
vk::UniquePipelineCache pipelineCache;
std::unique_ptr<QuadBuffer> quadBuffer;
std::unique_ptr<QuadPipeline> quadPipeline;
std::unique_ptr<QuadDrawer> quadDrawer;
std::unique_ptr<ShaderManager> shaderManager;
vk::ImageView lastFrameView;
vk::Offset2D lastFrameExtent;
std::unique_ptr<VulkanVMUs> vmus;
#ifdef VK_DEBUG
#ifndef __ANDROID__
vk::UniqueDebugUtilsMessengerEXT debugUtilsMessenger;

View File

@ -27,7 +27,6 @@
#include "shaders.h"
#include "rend/gui.h"
#include "rend/osd.h"
#include "quad.h"
class VulkanRenderer : public Renderer
{
@ -42,8 +41,6 @@ public:
screenDrawer.Init(&samplerManager, &shaderManager);
screenDrawer.SetCommandPool(&texCommandPool);
quadPipeline.Init(&shaderManager, screenDrawer.GetRenderPass());
quadBuffer = std::unique_ptr<QuadBuffer>(new QuadBuffer());
#ifdef __ANDROID__
if (!vjoyTexture)
@ -85,7 +82,6 @@ public:
{
texCommandPool.Init();
screenDrawer.Init(&samplerManager, &shaderManager);
quadPipeline.Init(&shaderManager, screenDrawer.GetRenderPass());
#ifdef __ANDROID__
osdPipeline.Init(&shaderManager, vjoyTexture->GetImageView(), GetContext()->GetRenderPass());
#endif
@ -95,8 +91,6 @@ public:
{
DEBUG_LOG(RENDERER, "VulkanRenderer::Term");
GetContext()->WaitIdle();
quadBuffer = nullptr;
quadPipeline.Term();
osdBuffer.reset();
vjoyTexture.reset();
textureCache.Clear();
@ -286,7 +280,6 @@ private:
fogTexture->SetCommandBuffer(nullptr);
}
std::unique_ptr<QuadBuffer> quadBuffer;
std::unique_ptr<Texture> fogTexture;
CommandPool texCommandPool;
@ -295,7 +288,6 @@ private:
ScreenDrawer screenDrawer;
TextureDrawer textureDrawer;
std::vector<std::unique_ptr<Texture>> framebufferTextures;
QuadPipeline quadPipeline;
OSDPipeline osdPipeline;
std::unique_ptr<Texture> vjoyTexture;
std::unique_ptr<BufferData> osdBuffer;